利⽤C++创建⼀个游戏(3)游戏地图绘制(代码+注释)⾸先注意的是我们要将地图素材放置项⽬⽂件夹中。 #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类型见 blog.csdn/wanghaofeng/article/details/6632165
*/
/
/ 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⾏
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 (ssage != 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);