#include "stdafx.h"
#include "MyGameFrame.h"
#include <stdio.h>
#include <stack> //堆栈类
using namespace std;
//定义全局变量
HWND hWnd;
HINSTANCE hInst;
HDC hdc, mdc, bufdc;
HBITMAP bmp, ball,tile;
DWORD tPre, tNow;
const int rows = 8, cols = 8;
int nowPos; //当前位置
int prePos; //
bool find_w;
stack<int> path;
int record[rows*cols];//记录历史路径
//0表示墙。1表示路径
int mapIndex[rows*cols] =
{
0,2,0,0,0,0,0,0,
0,1,0,1,1,1,1,0,
0,1,0,1,0,1,1,0,
0,1,0,0,0,1,1,0,
0,1,1,1,1,1,1,0,
0,1,0,0,0,0,1,0,
0,0,1,1,1,1,1,0,
0,0,0,0,0,0,3,0
};
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitWindow(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
VOID AIPaint(HDC hdc);
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 初始化全局字符串
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitWindow(hInstance, nCmdShow))//初始化窗口
{
return FALSE;//如果不成功则返回FALSE,并退出程序
}
MSG msg; //创建消息类对象
// TODO: 在此放置运行代码。
//定义局部变量
int rowNum, colNum, i, x, y;
hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);
bmp = CreateCompatibleBitmap(hdc, cols * 50, rows * 50);
SelectObject(mdc, bmp);
tile = (HBITMAP)LoadImage(NULL, "tile.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);
ball = (HBITMAP)LoadImage(NULL, "ball2.bmp", IMAGE_BITMAP, 50, 50, LR_LOADFROMFILE);
//按照mapIndex 内容拼接位图形成迷宫背景
for (i = 0; i < rows*cols; i++) {
record[i] = mapIndex[i]; //记录走过的路径
rowNum = i / cols; //求行号
colNum = i % cols; //求列号
x = colNum * 50; //计算贴图X坐标
y = rowNum * 50; //计算贴图Y坐标
SelectObject(bufdc, tile);
if (!mapIndex[i])
BitBlt(mdc, x, y, 50, 50, bufdc, 0, 0, SRCCOPY); //墙
else {
//通道
//找到迷宫入口
if (mapIndex[i] == 2) {
nowPos = i;
path.push(i); //入栈
record[i] = 0; //在记录路径中将入口标记为墙
}
BitBlt(mdc, x, y, 50, 50, bufdc, 0, 0, WHITENESS);
}
}
prePos = cols * rows + 1;
AIPaint(hdc);
// 主消息循环:
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);//赋初值
while (msg.message != WM_QUIT) //进入游戏消息循环:
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg); //获得游戏玩家输入的消息;
DispatchMessage(&msg);//分配玩家消息并响应用户消息。
}
else
{
tNow = GetTickCount();
if (tNow - tPre >= 100)
AIPaint(hdc);
}
}
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, MAKEINTRESOURCE(IDI_MYGAMEFRAME)),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),NULL,
_T("GameFrame"),
LoadIcon(NULL,MAKEINTRESOURCE(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, 427, 450, 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)
{
switch (msg) //判断消息
{
//esc退出程序
case WM_KEYDOWN:
if (wparam == VK_ESCAPE)
PostQuitMessage(0);
break;
case WM_CREATE:
//执行初始化代码
return(0);
break;
case WM_DESTROY:
//关闭程序,发送WM_QUIT消息
PostQuitMessage(0);
return(0);
break;
default:
break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
void AIPaint(HDC hdc)
{
int rowNum, colNum, x, y, up, down, left, right;
//清除上一次贴图
rowNum = prePos / cols;
colNum = prePos % cols;
x = colNum * 50;
y = rowNum * 50;
SelectObject(bufdc, ball);
//绘制墙
BitBlt(mdc, x, y, 50, 50, bufdc, 0, 0, WHITENESS);
//计算小球位置
rowNum = nowPos / cols;
colNum = nowPos % cols;
x = colNum * 50;
y = rowNum * 50;
//绘制小球
SelectObject(bufdc, ball);
BitBlt(mdc, x, y, 50, 50, bufdc, 0, 0, SRCCOPY);
//回溯算法
if (!find_w) {
up = nowPos - cols; //减一行
down = nowPos + cols; //加一行
left = nowPos - 1; //减一格
right = nowPos + 1; //增一格
//往上走
if (up >= 0 && record[up]) {
path.push(up); //向上的方向入栈
record[up] = 0; //历史路径数组中标记为墙,向上方向已走过
prePos = nowPos; //将当前位置记录为历史位置
nowPos = up; //更新位置
/*找到出口*/
if (mapIndex[nowPos] == 3)
find_w = true;
}
//往下走
else if (down <= cols * rows - 1 && record[down]) {
path.push(down);
record[down] = 0;
prePos = nowPos;
nowPos = down;
/*找到出口*/
if (mapIndex[nowPos] == 3)
find_w = true;
}
//往左走
else if (left >= rowNum * cols&&record[left]) {
path.push(left);
record[left] = 0;
prePos = nowPos;
nowPos = left;
/*找到出口*/
if (mapIndex[nowPos] == 3)
find_w = true;
}
//往右走
else if (right <= (rowNum + 1)*cols - 1 && record[right])
{
path.push(right);
record[right] = 0;
prePos = nowPos;
nowPos = right;
/*找到出口*/
if (mapIndex[nowPos] == 3)
find_w = true;
}
//无可移动方格
//返回上一步
else {
path.pop(); //移除栈顶元素
prePos = nowPos;
nowPos = path.top(); //返回栈顶元素
}
}
BitBlt(hdc, 10, 10, cols * 50, rows * 50, mdc, 0, 0, SRCCOPY);
tPre = GetTickCount();
}
结果如图所示