首先注意的是我们要将地图素材放置项目文件夹中。
#include "stdafx.h" #include "MyGameFrame.h" //源cpp文件引申出的头文件 也可以用resource.h代替 #include <stdio.h> //标准输入输出头文件 // 全局变量: HINSTANCE hInst; // 当前实例 HWND hWnd; HDC mdc; //窗口DC HDC hdc; HBITMAP fullmap; //地图 const int cols = 8; const int rows = 8; // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitWindow(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 初始化全局字符串 MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitWindow(hInstance, nCmdShow))//初始化窗口 { return FALSE;//如果不成功则返回FALSE,并退出程序 } /* MSG类型见 https://blog.csdn.net/wanghaofeng/article/details/6632165 */ MSG msg; //创建消息类对象 // TODO: 在此放置运行代码。 HDC hdc = GetDC(hWnd);//创建内存DC mdc = CreateCompatibleDC(hdc);//创建窗口DC,CreateCompatibleDC( )函数建立建立内存设备描述表,把存储在内存DC上的位图贴到窗口DC中 HDC bufdc = CreateCompatibleDC(hdc); //文件名 char filename[20] = ""; //行列及坐标 int rowNum, colNum; int i, x, y; //---------------------------------------------平面地图贴图方式-------------------------------------------------------------- //地图数组 int mapIndex[64] = { 2,2,2,2,0,1,0,1, //第1行 0,2,2,0,0,0,1,1, //第2行 0,0,0,0,0,0,0,1, //第3行 2,0,0,0,0,0,2,2, //第4行 2,0,0,0,0,2,2,2, //第5行 2,0,0,0,2,2,0,0, //第6行 0,0,2,2,2,0,0,1, //第7行 0,0,2,0,0,0,1,1 //第8行 }; fullmap = CreateCompatibleBitmap(hdc, cols * 50, rows * 50);//cols列数 rows行数 SelectObject(mdc, fullmap); //存储三种不同的地图格式 HBITMAP map[3]; //加载各图块位图 for (i = 0; i<3; i++) { sprintf_s(filename, "map%d.bmp", i); map[i] = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE); } //计算图块贴图位置并进行地图拼接并绘制的 for (i = 0; i<rows*cols; i++) { SelectObject(bufdc, map[mapIndex[i]]); rowNum = i / cols; //求行编号 colNum = i % cols; //求列编号 x = colNum * 50; //求贴图X 坐标 y = rowNum * 50; //求贴图Y 坐标 BitBlt(mdc, x, y, 50, 50, bufdc, 0, 0, SRCCOPY); //地图拼接 } //---------------------------------------------------------------------------------------------------------------------------- SelectObject(mdc, fullmap); BitBlt(hdc, 0, 0, cols * 50, rows * 50, mdc, 0, 0, SRCCOPY); //主消息循环: PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);//赋初值 while (msg.message != WM_QUIT) //进入游戏消息循环: { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); //获得游戏玩家输入的消息; DispatchMessage(&msg);//分配玩家消息并响应用户消息。 } } return (int)msg.wParam; } // // 函数: MyRegisterClass() // // 注册Windows类,一款游戏有且仅有一个主窗口,与游戏程序唯一对应。创建游戏窗口前要填写窗口类结构体WNDCLASSEX // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex = { wcex.cbSize = sizeof(WNDCLASSEX), CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW, WndProc,0,0, hInstance, LoadIcon(hInstance, (LPCTSTR)IDI_MYGAMEFRAME), LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1),NULL, _T("GameFrame"), LoadIcon(NULL,(LPCTSTR)IDI_SMALL) }; return RegisterClassEx(&wcex); } // // 函数: InitInstance(HINSTANCE, int) // // 目的: 保存实例句柄并创建主窗口 // // 注释: // // 在此函数中,我们在全局变量中保存实例句柄并 // 创建和显示主程序窗口。 // BOOL InitWindow(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow ( _T("GameFrame"), _T("游戏框架"), WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,//普通样式,不能改变大小,不能最大化 CW_USEDEFAULT, CW_USEDEFAULT, 400, 400, nullptr, nullptr, hInstance, nullptr ); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理主窗口的消息。 // // WM_COMMAND - 处理应用程序菜单 // WM_PAINT - 绘制主窗口 // WM_DESTROY - 发送退出消息并返回 // // LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; //用于WM_PAINT switch (msg) //判断消息 { case WM_CREATE: //执行初始化代码 return(0); break; case WM_PAINT: //确定窗口是否有效 hdc = BeginPaint(hwnd, &ps); //执行绘制代码 SelectObject(mdc, fullmap); //图像重绘处要加上这两句代码 BitBlt(hdc, 0, 0, cols * 50, rows * 50, mdc, 0, 0, SRCCOPY); //绘制 //结束代码 EndPaint(hwnd, &ps); return(0); break; case WM_DESTROY: //关闭程序,发送WM_QUIT消息 PostQuitMessage(0); return(0); break; default: break; } return (DefWindowProc(hwnd, msg, wparam, lparam)); }
测试结果如下:
同样我们要绘制斜角地图,我们先将地图大小做更换
全局变量里更改
const int cols = 8; const int rows = 8;
同样我们要绘制斜角地图,先将标线部分更换为
//-----------------------------------------斜角地图贴图方式(需把其他贴图方式注释掉)------------------------------------------ //地图数组 int mapIndex[100] = { 2,2,2,2,2,0,1,0,1,0, //第1行 3,3,2,2,0,0,0,1,1,0, //第2行 3,0,0,0,0,0,0,0,1,2, //第3行 2,2,0,0,0,0,0,2,2,2, //第4行 2,2,0,0,0,0,2,2,2,2, //第5行 2,2,0,0,0,2,2,0,0,2, //第6行 2,0,0,2,2,2,0,0,1,0, //第7行 0,0,2,0,0,0,1,1,1,1, //第8行 0,2,0,3,3,3,3,3,3,1, //第9行 2,0,3,3,3,3,3,3,3,3 //第10行 }; //-------------------景物地图贴图方式使用----------------------------------------- //景物数组sceneIndex[100]: int sceneIndex[100] = { 0,2,2,0,2,0,1,0,1,1, //景物 0,0,0,0,0,0,0,1,1,0, 0,0,0,0,0,0,1,0,1,0, 0,0,1,0,1,0,0,0,2,0, 2,2,0,0,1,0,0,0,0,2, 0,0,0,0,0,0,0,0,0,0, 0,0,1,0,0,0,0,0,1,0, 0,0,0,0,0,0,1,1,1,1, 1,0,0,0,0,0,0,0,0,1, 2,0,0,0,0,0,0,0,0,0 }; //----------------------------------------------------------------------------------- //存储四种不同的地图格式 HBITMAP map[4]; //xstart与ystart表示第一张图块左上角贴图坐标 int xstart, ystart; xstart = 32 * (rows - 1);//每个菱形的大小为64*32所以第0行第0列小图块坐标应该为此应该是(行数-1)*32 ystart = 160; //从y=160处开始绘制地图(即窗口高1/3处开始) fullmap = (HBITMAP)LoadImage(NULL, "bgtwo.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE); SelectObject(mdc, fullmap); for (i = 0; i<4; i++) { sprintf_s(filename, "maptwo%d.bmp", i); map[i] = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 128, 32, LR_LOADFROMFILE); } //载入景物位图 HBITMAP scene[2]; for (i = 0; i<2; i++) { sprintf_s(filename, "scene%d.bmp", i + 1); scene[i] = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 100, 60, LR_LOADFROMFILE); } //计算图块贴图位置程序代码 for (i = 0; i<rows*cols; i++) { SelectObject(bufdc, map[mapIndex[i]]); rowNum = i / cols; //求行编号 colNum = i % cols; //求列编号 x = xstart + colNum * 32 + rowNum * (-32); //求贴图X 坐标 y = ystart + rowNum * 16 + colNum * 16; //求贴图Y 坐标 BitBlt(mdc, x, y, 64, 32, bufdc, 64, 0, SRCAND); //透明处理 BitBlt(mdc, x, y, 64, 32, bufdc, 0, 0, SRCPAINT); //贴图坐标修正代码 //-------------------景物地图贴图方式使用----------------------------------------- switch (sceneIndex[i]) { case 1: SelectObject(bufdc, scene[0]); BitBlt(mdc, x + 7, y - 44, 50, 60, bufdc, 50, 0, SRCAND); //景物1 BitBlt(mdc, x + 7, y - 44, 50, 60, bufdc, 0, 0, SRCPAINT); break; case 2: SelectObject(bufdc, scene[1]); BitBlt(mdc, x + 7, y - 30, 50, 60, bufdc, 50, 0, SRCAND); //景物2 BitBlt(mdc, x + 7, y - 30, 50, 60, bufdc, 0, 0, SRCPAINT); break; } //------------------------------------------------------------------------------- } SelectObject(mdc, fullmap); BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
然后更换窗口大小 :(InitWindow()函数中)
HWND hWnd = CreateWindow ( _T("GameFrame"), _T("游戏框架"), WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,//普通样式,不能改变大小,不能最大化 CW_USEDEFAULT, CW_USEDEFAULT,640,480, nullptr, nullptr, hInstance, nullptr );
更换绘制代码:(WndProc()函数中)
SelectObject(mdc, fullmap); BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
效果分别如下: