现在实现地图贴图。
因为没有拿到手绘板,所以用随便做了两个材质用于测试:


再次看源文件 PhantomAndCrimsonSolitaire。其消息循环使用的是 GetMessage
:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
除了使用 GetMessage
,还有一个进行消息循环的方法是使用 PeekMessage
. GetMessage
在消息队列没有消息时会一直等待消息,直到有消息了才返回一个值;而 PeekMessage
则只会判断一下现在有没有消息,如果没有,它也不会等待,而是直接返回值表示没有取到消息。对于一个游戏程序,消息处理是特别频繁的。使用 PeekMessage
可以帮我们更好地异步处理消息。所以将其修改为:
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); // 初始化
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg); // 获取消息
DispatchMessage(&msg); // 分配消息并响应
}
}
要显示地图,先想一想我们的基本步骤:
- 将材质文件加载到一个内存 DC 中;
- 将地图指定到一个内存 DC 中,然后用材质刷上去;
- 将地图的内存 DC 贴到设备环境句柄 hdc 中.
由此可见,除了 mdc 这个内存 DC 句柄,我们还需要创建一个句柄. 故为地图创建一个位图句柄.
目光返回到全局变量声明的部分,所有的全局句柄如下:
HBITMAP hBackGround; // 背景位图句柄
HBITMAP hMap; // 地图句柄
HDC hdc, mdc; // 设别环境句柄与内存设备环境句柄
HDC mMapDC; // 为地图指定的内存DC
我的游戏应该使用一个 12x12 的二维方块地图,每个单元为一张 16x16 的贴图。那么占用的像素就是 12x16 = 192. 不过这也太小了,所以不妨设每个单元格的大小为50,那么地图大小为 600x600. 为方便以后再修改,把单元格大小也加到宏定义中。
#define MAX_LOADSTRING 100
#define WINDOW_WIDTH 1280 // 窗口宽度
#define WINDOW_HEIGHT 720 // 窗口高度
#define CELL_SIZE 50 // 单元格边长
在工程目录下新建一个 res 文件夹,将 stone.bmp 和 ground.bmp 放进去,重命名为 ground0.bmp 和 ground1.bmp.
现在开始设计函数 Map_Paint()
函数:
首先别忘记声明函数:
VOID Map_Paint(HWND hwnd);
具体如何将贴图一个一个贴上去呢?
现在这里有两个贴图 ground0.bmp 和 ground1.bmp,我们想按自己的想法在 600x600 地图的各个单元格填上这两个贴图。
既然两个贴图都要被载入,不妨定义一个位图句柄数组 HBITMAP hTexture[2]
.
为了按自己的想法绘出地图,给出一个地图数组,用来表示所绘制材质的下标:
unsigned int myMap[12][12] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1,