用MFC+GDI编写MapEdit的心得总结

一 地图格式

对于游戏编程而言,如果已经有人为我们写好了底层的代码,那么我们所要关心的就是游戏本身了。在

确定了游戏的类型,规划出游戏的结构之后,恐怕我们不能马上开始编写代码,我们还需要了解一些文

件的格式。就像我要写的这个地图编辑器,我自己为它定义了一个格式(主要参考了怪盗KID制作的《永

远的伊苏》的地图格式)。

我的格式如下:

/****文件头****/
8字节标志 JSMAP0.1
4字节文件大小
4字节文件头大小
2字节地图宽度,以格子为单位
2字节地图高度,以格子为单位
2字节地图总的层数
2字节地图中人物所在的层数
2字节资源ID
1字节Tile的规格(16/32)
1字节主角默认方向
2字节主角默认X坐标
2字节主角默认Y坐标
/****主要数据****/
4*N字节的每层数据偏移量列表
宽*高*N字节的实际数据

注:使用16X16的Tile时应使用256X240X32bits的bmp位图,32X32的Tile资源为256X480X32bits的bmp位

图。

如图

用MFC+GDI编写MapEdit的心得总结_第1张图片

略过前8字节的标志,可以看到test.map的文件大小为467CH,文件头大小是20H,宽3CH,高32H,地图一

共分3层,人物分布在第2层上,资源ID是1(data/1.bmp),Tile规格为10H(也就是16X16的大小),后

面的主角默认方向、X坐标、Y坐标都是0,因为我忘了把设置主角的对话框做进去了。然后是第一层、第

二层和事件层的偏移量。一二两层都属于图形层,0表示空,1-241表示对应的Tile编号。事件层结构如

下:
struct EventLayer
{
    unsigned moveable:1;    // 是否阻挡(1表示不能通过)
    unsigned eventnum:7;    // 事件编号(0表示空事件,支持1-127个固定地图事件,例如,1号事

件对应的脚本就是test_1.scr)
};


二 用MFC和GDI编写MapEdit

说到2D地图编辑器,RPGMaker可以说是一个典范,我开始时的目标就是RM,但现在后看还是有很大的差

距的。

DirectX是个好东西,但是初始化什么的有点麻烦,我第一个想到的是用HoHo4引擎来处理图像显示部分

,但经过一天的测试,发现HoHo4只支持4pixels整数倍的窗口,否则会花屏。没办法,只能回去用GDI慢

慢画了。不过效果还不错,呵呵。

我对MFC并不是很熟悉,编写时遇到了很多问题,下面说几个典型的,希望对大家有所帮助。

Q:类似RM那样的界面是怎么做的?
A:用拆分窗口(CSplitterWnd)。

Q:如何禁用CSplitterWnd拖动窗格分割线的功能?
A:创建CSplitterWnd的派生类,并重载OnLButtonDown和OnMouseMove两个成员函数。

Q:为什么拆分出的左侧窗口的宽度总是零?
A:在CMainFrame的OnCreate过程中使用SetColumnInfo和SetRowInfo设置拆分窗格的大小。

Q:我为MapEdit增加了画笔工具,可是为什么快速移动鼠标时画上的点是断断续续的?
A:这是由于MouseMove事件是以固定的时间间隔发出的,所以当鼠标移动速度过快时,窗口接收到的鼠

标采样相对不足,导致画出的线不是连续的点。有一种解决的办法就是增加连续画线函数MoveTo()和

LineTo()。

Q:各个视图中的数据信息是如何共享的?
A:我对文档/视图结构不是很了解,所以在创建工程的时候取消了这一结构,而在多个视图共享数据时

很无奈的用了全局变量theApp。


三 地图上的事件

地图事件是建立在地图本身之上的,它们之间有点联系,但是联系又不是十分紧密。我喜欢将npc、事件

独立于地图,原因你去玩一下《圣2》就不难看出,每次进入同一个地图时npc总是从一个固定的坐标加

载进来。好了,似乎透露的太多了,下次我们讨论npc、事件和存档的问题。
 

MapEdit源代码请到http://download.csdn.net/user/leexuany下载,刚刚上传,还没通过审核

12月10日 12点14分

 

你可能感兴趣的:(游戏,struct,脚本,mfc,图形,引擎)