作者:Flysky 2005
注:写的十分粗糙,如果看不懂请对照KgameV1.0源代码浏览。
最好的游戏末过于RPG游戏了,但如果赢得大众的好评,那么必须要采用(甚至说现在是一种标准)斜45度地图、人物游戏引擎,下面我们分别展开分析。
一.地图数据结构
Soft的《圣剑英雄传二》定义的就不错,可以参考它的。 定义地图结构以前,我们要先定义Tile结构,分两种情况。
(1).物品、景物等按NPC处理(不规则处理,如“魔力宝贝”): typedef struct{ bool IsGround;//是否显示地表 short GroundPicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态 short GroundPicX; //地表材料在地表图片上的横坐标(以格子为坐标) short GroundPicY; //地表材料在地表图片上的纵坐标(以格子为坐标) short Block; //阻碍标志(ID_BLOCK_T,ID_BLOCK_F) short Hook; //陷阱标志(ID_HOOK_F,ID_HOOK_T …………) char HookScriptName[28]; char Reserve; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改cell结构时可避免重新编辑地图文件) }stCell;
具体我也不说什么了,注释都很清楚!
(2).物品、景物也按Tile处理但NPC按不规则处理(如:“仙剑奇侠转”,强烈不推荐!) typedef struct{ bool IsGround;//是否显示地表 short GroundPicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态 short GroundPicX; //地表材料在地表图片上的横坐标(以格子为坐标) short GroundPicY; //地表材料在地表图片上的纵坐标(以格子为坐标) bool IsObject1;//是否显示物品1 short Object1PicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态 short Object1PicX; //物体材料1在物体图片上的横坐标(以格子为坐标) short Object1PicY; //物体材料1在物体图片上的纵坐标(以格子为坐标) bool IsObject2; //是否显示物品2 short Object2PicNum; //地表图片页面编号(0~59),,,(0-55)页为静态,(56~59)页为动态 short Object2PicX; //物体材料2在物体图片上的横坐标(以格子为坐标) short Object2PicY; //物体材料2在物体图片上的纵坐标(以格子为坐标) short Block; //阻碍标志(ID_BLOCK_T,ID_BLOCK_F) short Hook; //陷阱标志(ID_HOOK_F,ID_HOOK_T …………) char HookScriptName[28]; char Reserve; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改cell结构时可避免重新编辑地图文件) }stCell;
太清楚了,我也不解释了!
下一步就是地图了,地图的处理不管是什么方法大同小异. int ID; //地图编号 char Name[32]; //地图名称(地图文件名) int Width; //宽度(以格子为坐标) 斜 int Height; //高度(以格子为坐标) 斜 int MapStartX,MapStartY; //左上角坐标 stCell **Cell; //动态格子 char FileName[32]; //当前地图文件名 char ScrFName[32]; //地图初始化脚本文件名 char Reserve[4]; //保留位,(我估计我们肯定还有想不到的一些信息,以后可以在这里添加,以免地图编辑完成之后,再修改Map_struct格式,破坏原先编好的地图文件)
//这里先不用看,到了那里再说。 LPDIRECTDRAWSURFACE7 lpDDS_MapBack; //地图临时保存点 LPDIRECTDRAWSURFACE7 lpDDS_TMouse; //Tile鼠标 int MapBx,MapBy; //用来优化机器
这样不就介绍完了吗?简单吧,不过后面的越来越难,做好心理准备。
二.坐标转换
各大文章在这里都快讲疯了,我不想说推理方法了,你记住以下函数就可以:
//斜45度的坐标转换成屏幕坐标 inline void MIToMD(int Dx,int Dy,int &Ix,int &Iy) { Ix=(TileWidth>>1)*(Dx-Dy);//转换为绝对坐标x Iy=(TileHeight>>1)*(Dx+Dy);//转换为绝对坐标y 大菱形 }
//屏幕坐标转换成斜45度的坐标 inline void MDToMI(int Ix,int Iy,int &Dx,int &Dy) { Dx=int(0.5*((Iy<<1)+Ix)/(TileWidth>>1)); Dy=int(0.5*((Iy<<1)-Ix)/(TileWidth>>1)); }
其中 #define TileWidth 32 //每个Tile的宽 #define TileHeight 16 //每个Tile的高
三.绘制地图
绘制地图有什么难的,错!地图绘制好了FPS能提高数倍。
传统的地图绘制方法:
for(int i=0;i<height;i++) { for(int t=0;t<width;t++) { 绘制。。。。。 } }
经过改进我这样做
if (MapBx!=x&&MaxBy!=y) { for(int i=0;i<height;i++) { for(int t=0;t<width;t++) { 绘制。。。。。 更新MaxBx和MaxBy 备份地图(存成图片) } } } else { 还原地图(取出图片) }
这样空闲状态的FPS就会提升,什么?还想提升,这样办吧!
推理方法从略(其实我也不记得的,春天写的):
#define MapDMX int(0.5*((ScreenHeight<<1)+ScreenWidth)/(TileWidth>>1))+1 //最大画出点X #define MapDMY int(0.5*(ScreenHeight<<1)/(TileWidth>>1))+1 //最大画出点Y #define MapDSY int(0.5*(-ScreenWidth)/(TileWidth>>1))-1 //最小画出点Y(特殊)
然后 if (MapBx!=x&&MaxBy!=y) { for (int Y=IntSizeL(MapStartY+MapDSY,0); Y<IntSizeS(MapStartY+MapDMY,Height); Y++) { for (int X=IntSizeL(MapStartX-1,0); X<IntSizeS(MapStartX+MapDMX,Width); X++) { 绘制。。。。。 更新MaxBx和MaxBy 备份地图(存成图片) } } else { 还原地图(取出图片) }
其中IntSizeL取两个数大的,IntSizeS取两个数小的!
速度优化到极限了,好了,先写到着,下一次我再说遮挡。
资讯仅供参考,不代表本站(GameRes.com)观点,此信息由sea_bug提交。
|