我的做法:
每屏大约显示20*15个格子(考虑屏幕的象素级卷轴和物体高度,实际是679个),这些格子的显示顺序可以用实时计算来确定,但我采用了更快的方法,对于每个格子我定义一个结构对应这些格子
struct GRID
{
short int x,y; //格子在屏幕上坐标
short int m,n; //格子在数组里的坐标的偏移值
} *grid;
因为格子的数量在一定的分辨率下是固定,每个格子(结构)中的四个变量值也是固定的,所以我先将它们算出来,顺序保存在文件中。在游戏图形初始化过程中,将这个文件载入内存,用grid指向它,于是地图显示就变成了:
for(i=0;i<679;i++)
draw_pat(grid[i].x,grid[i].y,map[grid[i].m+map_offx][grid[i].n+map_offy]);
map_offx和map_offy是当前屏幕相对地图的偏移值,相当于你程序中的pm.sx和pm.sy
map是地图数据,其中的值表示地物编号。
另外:
你的地物遮挡算法一看你那张图就知道了。但用递归似乎效率太低(涉及环境变量和参数的压栈出栈),而且容易出问题,比如两个物体的修正区互相包含对方的物体编号点,就会发生死循环。当然这种情况在然实际当中不可能存在(物体空间上不交叠),但在程序中却实在是个隐患!
我的算法和你最大的不同就在于对物体图进行了横分,如果一个物体在横向上占了n个格子,我在显示地图时,就在相当于将这个图片横分了n份(实时划分),每份由它地面对应的格子决定显示顺序。具体的过程入下:
对于格子(11,8)中有物体编号(map[11][8]=33),则显示这个物体位于这个格子内的部分(就是图中分出的4,尺寸32xn)。
例如对于格子(8,8),如果它其中没有物体编号(map[8][8]=0),那么横向搜索一定格数,如果发现有物体编号(map[11][8]=33),根据搜索的距离(11-8=3)和这个物体的大小(4x2)判断是否应当在这个格子map[8][8]内显示物体,如果是(3<4),则根据相对于物体编号点的偏移画出物体相应的部分(就是图中分出的1,尺寸32xn)。如果没有发现需要显示的部分,再纵向搜索,方法相同。

我之前说采用分图效率损失比较大,是因为不分图时效率太高(采用上面的结构 grid显示的方法),因此分图的过程占的时间相对较多。假设原来显示一屏要10ms,采用分图的方法后为18ms,效率损失80%,但还是总体来说应该比你的方法用时少。因为采用分图的方法后,每屏要考虑的格子只有超出屏幕下方的,而不用考虑超出屏幕左右两侧的。