《走迷宫程序含自动迷宫生成.doc》由会员分享,可在线阅读,更多相关《走迷宫程序含自动迷宫生成.doc(13页珍藏版)》请在课桌文档上搜索。
1、-迷宫程序。执行效果如下:程序间有足够多的注释,就不多作介绍了。代码如下:/ 程序名称:迷宫游戏/ 编译环境:Visual C+ 6.0 / 2010,Easy* 2011惊蛰版/ 作者:krissi / 最后修改:2011-3-12/#include #include #include / 定义全局变量/BYTE*g_imgMap = NULL;/ 迷宫地图SIZEg_szMap;/ 迷宫地图的尺寸IMAGEg_imgSight(360, 280);/ 游戏的视野RECTg_rtSight;/ 游戏的视野的围IMAGEg_imgItem(180, 20);/ 地图元素IMAGEg_imgGP
2、S;/ 迷你地图,用于显示游戏者在地图中的位置POINTg_ptGPS;/ 迷你地图的显示位置SIZEg_szGPS;/ 迷你地图的尺寸POINTg_ptPlayer;/ 游戏者的位置/ 枚举地图元素,兼做元素位置的 * 坐标enum MAPITEM MAP_WALL = 0, MAP_PLAYER = 20, MAP_GROUND = 40, MAP_MARKRED = 60, MAP_MARKGREEN = 80, MAP_MARKYELLOW = 100, MAP_ENTRANCE = 120, MAP_E*IT = 140, MAP_OUTSIDE = 160 ;/ 枚举用户的控制命令
3、enum CMD CMD_QUIT = 1, CMD_UP = 2, CMD_DOWN = 4, CMD_LEFT = 8, CMD_RIGHT = 16, CMD_MARKRED = 32, CMD_MARKGREEN = 64, CMD_MARKYELLOW = 128, CMD_CLEARMARK = 256 ;/ 函数声明/voidWele();/ 绘制游戏界面voidInitImage();/ 初始化游戏图片voidInitGame();/ 初始化游戏数据voidGetMazeSize();/ 提示用户输入迷宫大小voidMakeMaze(int width, int height)
4、;/ 生成迷宫:初始化注:宽高必须是奇数voidTravelMaze(int *, int y);/ 生成迷宫:遍历 (*, y) 四周MAPITEMGetMazeItem(int *, int y);/ 获取指定坐标的迷宫元素voidPaint();/ 绘制视野围的迷宫intGetCmd(int* c);/ 获取用户输入的命令voidDispatchCmd(int cmd);/ 处理用户输入的命令voidOnUp();/ 向上移动voidOnLeft();/ 向左移动voidOnRight();/ 向右移动voidOnDown();/ 向下移动voidOnMark(MAPITEM value
5、);/ 在地图中做标记boolCheckWin();/ 检查是否到出口boolQuit();/ 询问用户是否退出游戏/ 函数定义/ 主程序void main()/ 初始化initgraph(640, 480);/ 创立绘图窗口srand(unsigned)time(NULL);/ 设置随机种子/ 显示主界面Wele();/ 初始化InitImage();InitGame();/ 游戏过程int c;while( !(GetCmd(&c) = CMD_QUIT) & Quit() )DispatchCmd(c);Paint();if (CheckWin()break;/ 延时Sleep(100)
6、;/ 清理迷宫地图占用的存for(int * = 0; * g_szMap.c* + 2; *+)delete g_imgMap*;delete g_imgMap;/ 关闭图形模式closegraph();/ 绘制游戏界面void Wele()/ 绘制渐变色外框for(int i=0; i128; i+)setcolor(RGB(0, 0, (127 - i) 1), 490 + i, 370 + (i 1);/ 设置字体样式setcolor(WHITE);setbkmode(TRANSPARENT);/ 绘制标题setfont(36, 0, _T(宋体);outte*t*y(248, 40,
7、 _T(迷宫);/ 绘制操作说明setfont(12, 0, _T(宋体);outte*t*y(50, 382, _T(控制说明:);outte*t*y(74, 400, _T(方向键或 A/S/D/W:移动);outte*t*y(74, 418, _T(空格、Y、G:在地图上做红、黄、绿色 M 标记);outte*t*y(74, 436, _T(C:去除地图上的标记);outte*t*y(74, 454, _T(ESC:退出程序);/ 初始化游戏图片void InitImage()/ 预绘制游戏图片到 IMAGE 缓存可以修改为加载图片以获得更好效果SetWorkingImage(&g_im
8、gItem);cleardevice();/ 绘制 PLAYERsetorigin(MAP_PLAYER, 0);setfillstyle(YELLOW);setcolor(YELLOW);fillellipse(2, 2, 17, 17);setcolor(BLACK);line(7, 7, 7, 8);line(12, 7, 12, 8);arc(5, 6, 14, 14, 3.34, 6.08);/ 绘制墙壁setorigin(MAP_WALL, 0);setfillstyle(BROWN, PATTERN_FILL, *20*20*20*ff*04*04*04*ff);setcolor
9、(BROWN);bar(1, 1, 18, 18);rectangle(0, 0, 19, 19);/ 绘制红色标记setorigin(MAP_MARKRED, 0);setcolor(RED);moveto(5, 15);linerel(0, -10);linerel(5, 5);linerel(5, -5);linerel(0, 10);/ 绘制绿色标记setorigin(MAP_MARKGREEN, 0);setcolor(GREEN);moveto(5, 15);linerel(0, -10);linerel(5, 5);linerel(5, -5);linerel(0, 10);/
10、绘制黄色标记setorigin(MAP_MARKYELLOW, 0);setcolor(YELLOW);moveto(5, 15);linerel(0, -10);linerel(5, 5);linerel(5, -5);linerel(0, 10);/ 绘制入口setorigin(MAP_ENTRANCE, 0);setcolor(GREEN);setfont(12, 0, _T(宋体);outte*t*y(4, 4, _T(入);/ 绘制出口setorigin(MAP_E*IT, 0);outte*t*y(4, 4, _T(出);/ 绘制迷宫外面的空地setorigin(MAP_OUTSI
11、DE, 0);setfillstyle(GREEN, PATTERN_FILL, *50*55*22*20*05*55*22*02);bar(0, 0, 19, 19);/ 恢复坐标系setorigin(0, 0);/ 显示作者SetWorkingImage();setcolor(BLUE);TCHAR author = _T(Powered by zhaoh1987qq.);outte*t*y(471, 4, author);setcolor(LIGHTBLUE);outte*t*y(470, 3, author);/ 初始化游戏数据void InitGame()/ 提示用户输入迷宫大小Ge
12、tMazeSize();/ 初始化参数if (g_imgMap != NULL)/ 清理迷宫地图占用的存for(int * = 0; * g_szMap.cy)g_szGPS.c* = 100; g_szGPS.cy = (int)(100.0 * g_szMap.cy / g_szMap.c* + 0.5);elseg_szGPS.cy = 100; g_szGPS.c* = (int)(100.0 * g_szMap.c* / g_szMap.cy + 0.5);Resize(&g_imgGPS, g_szGPS.c*, g_szGPS.cy);g_ptGPS.* = 530 + 50 -
13、 g_szGPS.c* / 2;g_ptGPS.y = 370 + 50 - g_szGPS.cy / 2;/ 画迷你地图外框setcolor(RED);rectangle(g_ptGPS.* - 1, g_ptGPS.y - 1, g_ptGPS.* + g_szGPS.c*, g_ptGPS.y + g_szGPS.cy);/ 画迷你地图入口和出口setcolor(YELLOW);moveto(g_ptGPS.* - 8, g_ptGPS.y + g_szGPS.cy / g_szMap.cy);linerel(7, 0);linerel(-3, -3);moverel(3, 3);lin
14、erel(-3, 3);moveto(g_ptGPS.* + g_szGPS.c*, g_ptGPS.y + g_szGPS.cy - g_szGPS.cy / g_szMap.cy);linerel(7, 0);linerel(-3, -3);moverel(3, 3);linerel(-3, 3);/ 绘制游戏区Paint();/ 提示用户输入迷宫大小void GetMazeSize()g_szMap.c* = g_szMap.cy = 0;/ 获取用户输入的宽高TCHAR s4;while(g_szMap.c* 200)InputBo*(s, 4, _T(请输入迷宫的宽度n围:20200
15、), _T(输入), _T(25);g_szMap.c* = _ttoi(s);while(g_szMap.cy 200)InputBo*(s, 4, _T(请输入迷宫的高度n围:20200), _T(输入), _T(25);g_szMap.cy = _ttoi(s);/ 确保宽高为奇数if (g_szMap.c* % 2 != 1) g_szMap.c*+;if (g_szMap.cy % 2 != 1) g_szMap.cy+;/ 生成迷宫:初始化注:宽高必须是奇数void MakeMaze(int width, int height)if (width % 2 != 1 | height
16、 % 2 != 1)return;int *, y;/ 定义迷宫尺寸,并分配迷宫存g_imgMap = new BYTE*width + 2;for(* = 0; * width + 2; *+)g_imgMap* = new BYTEheight + 2;memset(g_imgMap*, MAP_WALL, height + 2);/ 定义边界for (* = 0; * = width + 1; *+)g_imgMap*0 = g_imgMap*height + 1 = MAP_GROUND;for (y = 1; y = height; y+)g_imgMap0y = g_imgMapw
17、idth + 1y = MAP_GROUND;/ 定义入口和出口g_imgMap12 = MAP_ENTRANCE;g_imgMapwidthheight - 1 = MAP_E*IT;/ 从任意点开场遍历生成迷宫TravelMaze(rand() % (width - 1) & 0*fffe) + 2, (rand() % (height - 1) & 0*fffe) + 2);/ 将边界标记为迷宫外for (* = 0; * = width + 1; *+)g_imgMap*0 = g_imgMap*height + 1 = MAP_OUTSIDE;for (y = 1; y = heig
18、ht; y+)g_imgMap0y = g_imgMapwidth + 1y = MAP_OUTSIDE;/ 生成迷宫:遍历 (*, y) 四周void TravelMaze(int *, int y)/ 定义遍历方向int d42 = 0, 1, 1, 0, 0, -1, -1, 0;/ 将遍历方向乱序int n, t, i;for(i = 0; i 4; i+)n = rand() % 4;t = di0, di0 = dn0, dn0 = t;t = di1, di1 = dn1, dn1 = t;/ 尝试周围四个方向g_imgMap*y = MAP_GROUND;for(i = 0;
19、i 4; i+)if (g_imgMap* + 2 * di0y + 2 * di1 = 0)g_imgMap* + di0y + di1 = MAP_GROUND;TravelMaze(* + di0 * 2, y + di1 * 2);/ 递归/ 获取指定坐标的迷宫元素MAPITEM GetMazeItem(int *, int y)return (MAPITEM)g_imgMap*y;/ 绘制视野围的迷宫void Paint()int *1, y1;/ 绘制视野的迷宫SetWorkingImage(&g_imgSight);for(int * = g_rtSight.left; * =
20、g_rtSight.right; *+)for(int y = g_rtSight.top; y 1 & GetMazeItem(g_ptPlayer.*, g_ptPlayer.y - 1) != MAP_WALL)g_ptPlayer.y-;if (g_ptPlayer.y - g_rtSight.top 0)g_rtSight.top-;g_rtSight.bottom-;/ 向左移动void OnLeft()if (g_ptPlayer.* 1 & GetMazeItem(g_ptPlayer.* - 1, g_ptPlayer.y) != MAP_WALL & GetMazeItem
21、(g_ptPlayer.* - 1, g_ptPlayer.y) != MAP_ENTRANCE)g_ptPlayer.*-;if (g_ptPlayer.* - g_rtSight.left 0)g_rtSight.left-;g_rtSight.right-;/ 向右移动void OnRight()if (g_ptPlayer.* g_szMap.c* & GetMazeItem(g_ptPlayer.* + 1, g_ptPlayer.y) != MAP_WALL)g_ptPlayer.*+;if (g_rtSight.right - g_ptPlayer.* 5 & g_rtSight
22、.right = g_szMap.c*)g_rtSight.left+;g_rtSight.right+;/ 向下移动void OnDown()if (g_ptPlayer.y g_szMap.cy & GetMazeItem(g_ptPlayer.*, g_ptPlayer.y + 1) != MAP_WALL)g_ptPlayer.y+;if (g_rtSight.bottom - g_ptPlayer.y 4 & g_rtSight.bottom = g_szMap.cy)g_rtSight.top+;g_rtSight.bottom+;/ 在地图中做标记void OnMark(MAPI
23、TEM value)g_imgMapg_ptPlayer.*g_ptPlayer.y = value;/ 检查是否到出口bool CheckWin()if (g_ptPlayer.* = g_szMap.c* & g_ptPlayer.y = g_szMap.cy - 1)HWND hwnd = GetHWnd();if (MessageBo*(hwnd, _T(恭喜你走出来了!n您想再来一局吗?), _T(恭喜), MB_YESNO | MB_ICONQUESTION) = IDYES)InitGame();return false;elsereturn true;return false;/ 询问用户是否退出游戏bool Quit()HWND hwnd = GetHWnd();return (MessageBo*(hwnd, _T(您确定要退出游戏吗?), _T(询问), MB_OKCANCEL | MB_ICONQUESTION) = IDOK);. z.
链接地址:https://www.desk33.com/p-8455.html