C语言零基础项目:迷宫游戏!详细思路+源码分享

2022-12-28 0 353

每晚两个C词汇小工程项目,提高你的程式设计潜能!

地牢格斗游戏只不过有很各类型型,比如解救郡主的这款,又比如冲关的这款,其它的许多类型这儿就不细说了。但无论哪这款地牢格斗游戏,惟一维持不变的是地牢的同时实现而此核心理念功能,每这款地牢格斗游戏不外乎是依照他们的格斗游戏物理性质在地牢当中加进许多必要性的原素而已。

他们那时的主要就最终目标是用C词汇来同时实现地牢的原先机能,天然无毒,没加进任何人添加剂(即使没其它的譬如的机能)

C语言零基础项目:迷宫游戏!详细思路+源码分享

下面就是咱的设计图自动更新,以程序库easyX来配搭C词汇句法同时实现的地牢介面,接着也同时实现了比如许多按钮操作方式,边界检测这种的机能,总体而言却是总体性的。

本工程项目校对自然环境:Visual Studio 2019/2022,EasyX应用程序

标识符展现:

#include <stdio.h> #include <graphics.h> #include <time.h> ////////////////////////////////////////////////////// // 表述函数调用 // BYTE** g_aryMap = NULL; // 地牢世界地图 SIZE g_szMap; // 地牢世界地图的体积 IMAGE g_imgSight(360, 280); // 格斗游戏的视野 RECT g_rtSight; // 格斗游戏的视野的范围 IMAGE g_imgItem(180, 20); // 世界地图原素 IMAGE g_imgGPS; // 迷你世界地图,用于显示格斗游戏者在世界地图中的位置 POINT g_ptGPS; // 迷你世界地图的显示位置 SIZE g_szGPS; // 迷你世界地图的体积 POINT g_ptPlayer; // 格斗游戏者的位置 // 枚举世界地图原素,兼做元素位置的 x 坐标 enum MAPITEM { MAP_WALL = 0, MAP_PLAYER = 20, MAP_GROUND = 40, MAP_MARKRED = 60, MAP_MARKGREEN =80, MAP_MARKYELLOW = 100, MAP_ENTRANCE = 120, MAP_EXIT = 140, MAP_OUTSIDE = 160 }; // 枚举用户的控制命令 enumCMD { 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 }; ////////////////////////////////////////////////////// // 函数声明 // void Welcome(); // 绘制格斗游戏介面 void InitImage(); // 初始化格斗游戏图片 void InitGame(); // 初始化格斗游戏数据 void GetMazeSize(); // 提示用户输入地牢大小 void MakeMaze(int width, int height); // 生成地牢:初始化(注:宽高必须是奇数) void TravelMaze(int x, int y); // 生成地牢:遍历 (x, y) 四周 MAPITEM GetMazeItem(int x, int y); void Paint(); // 绘制视野范围内的地牢 int GetCmd(); 的命令 void DispatchCmd(int cmd); // 处理用户输入的命令 void OnUp(); // 向上移动 void OnLeft(); // 向左移动 void OnRight(); // 向右移动 void OnDown(); // 向下移动 void OnMark(MAPITEM value); // 在世界地图中做标记 bool CheckWin(); // 检查是否到出口 bool Quit(); // 询问用户是否退出格斗游戏 ////////////////////////////////////////////////////// // 函数表述 // // 主程序 void main() { // 初始化 initgraph(640, 480); // 创建绘图窗口 srand((unsigned)time(NULL)); // 设置随机种子 // 显示主介面 Welcome(); // 初始化InitImage(); InitGame();// 格斗游戏过程 int c; while( !(((c = GetCmd()) & CMD_QUIT) && Quit()) ) { DispatchCmd(c); Paint();if (CheckWin()) break; // 延时 Sleep(100); } // 清理地牢世界地图占用的内存 for(int x = 0; x < g_szMap.cx + 2; x++) delete[] g_aryMap[x]; delete [] g_aryMap; // 关闭图形模式 closegraph(); } // 绘制格斗游戏介面 void Welcome() { // 绘制渐变色外框 for(int i=0; i<128; i++) { setlinecolor(RGB(0, 0, (127 – i) << 1)); rectangle(149 – i, 109– (i >>1), 490 + i, 370 + (i >> 1)); } // 设置字体样式 settextcolor(WHITE); setbkmode(TRANSPARENT); // 绘制标题settextstyle(36, 0, _T(“宋体”)); outtextxy(248, 40, _T(“迷  宫”)); // 绘制操作方式说明 settextstyle(12, 0, _T(“宋体”)); outtextxy(50, 382, _T(“控制说明:”)); outtextxy(74, 400, _T(“方向键或 A/S/D/W:移动”)); outtextxy(74, 418, _T(“空格、Y、G:在世界地图上做红、黄、绿色 M 标记”)); outtextxy(74, 436, _T(“C:清除世界地图上的标记”)); outtextxy(74, 454, _T(“ESC:退出程序”)); } // 初始化格斗游戏图片 void InitImage() { // 预绘制格斗游戏图片到 IMAGE 缓存(可以修改为加载图片以获得更好效果)SetWorkingImage(&g_imgItem); cleardevice();// 绘制 PLAYER setorigin(MAP_PLAYER, 0); setfillcolor(YELLOW); setlinecolor(YELLOW); fillellipse(2, 2, 17, 17); setlinecolor(BLACK); line(7, 7, 7, 8); line(12, 7, 12, 8); arc(5, 6, 14, 14, 3.34, 6.08); // 绘制墙壁 setorigin(MAP_WALL, 0); settextcolor(BROWN); setfillstyle((BYTE*)“\x20\x20\x20\xff\x04\x04\x04\xff”); setlinecolor(BROWN); solidrectangle(1, 1, 18, 18); rectangle(0, 0, 19, 19); // 绘制红色标记 setorigin(MAP_MARKRED, 0); setlinecolor(RED); moveto(5, 15); linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10); // 绘制绿色标记setorigin(MAP_MARKGREEN,0); setlinecolor(GREEN); moveto(5, 15); linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10); // 绘制黄色标记 setorigin(MAP_MARKYELLOW, 0); setlinecolor(YELLOW); moveto(5, 15); linerel(0, -10); linerel(5, 5); linerel(5, -5); linerel(0, 10); // 绘制入口 setorigin(MAP_ENTRANCE, 0); setlinecolor(GREEN); settextstyle(12, 0, _T(“宋体”)); outtextxy(4, 4, _T(“入”)); // 绘制出口setorigin(MAP_EXIT,0); outtextxy(4, 4, _T(“出”)); // 绘制地牢外面的空地 setorigin(MAP_OUTSIDE, 0); settextcolor(GREEN); setfillstyle((BYTE*)“\x50\x55\x22\x20\x05\x55\x22\x02”); solidrectangle(0, 0, 19, 19); // 恢复坐标系 setorigin(0, 0); // 显示作者 SetWorkingImage(); settextcolor(BLUE); TCHAR author[] = _T(“Powered by [email protected]); outtextxy(471, 4, author); settextcolor(LIGHTBLUE); outtextxy(470, 3, author); } // 初始化格斗游戏数据 void InitGame() { // 提示用户输入地牢大小 GetMazeSize(); // 初始化参数 if (g_aryMap != NULL) {// 清理地牢世界地图占用的内存 for(int x = 0; x < g_szMap.cx + 2; x++) delete[] g_aryMap[x]; delete[] g_aryMap; } MakeMaze(g_szMap.cx, g_szMap.cy);// 创建地牢 g_ptPlayer.x = 2; // 设置格斗游戏者的位置 g_ptPlayer.y = 2; g_rtSight.left =0; // 设置视野范围 g_rtSight.top = 0; g_rtSight.right = 17; g_rtSight.bottom= 13; // 设置 GPS 显示区 setfillcolor(BLUE); solidrectangle(522, 368, 637, 471); if (g_szMap.cx > g_szMap.cy) { g_szGPS.cx = 100; g_szGPS.cy = (int)(100.0 * g_szMap.cy / g_szMap.cx + 0.5); } else { g_szGPS.cy = 100; g_szGPS.cx = (int)(100.0 * g_szMap.cx / g_szMap.cy + 0.5); } Resize(&g_imgGPS, g_szGPS.cx, g_szGPS.cy); g_ptGPS.x =530 + 50 – g_szGPS.cx / 2; g_ptGPS.y = 370 + 50 – g_szGPS.cy / 2; // 画迷你世界地图外框setlinecolor(RED); rectangle(g_ptGPS.x –1, g_ptGPS.y – 1, g_ptGPS.x + g_szGPS.cx, g_ptGPS.y + g_szGPS.cy); // 画迷你世界地图入口和出口setlinecolor(YELLOW); moveto(g_ptGPS.x –8, g_ptGPS.y + g_szGPS.cy / g_szMap.cy); linerel(7, 0); linerel(-3, -3); moverel(3, 3); linerel(-3, 3); moveto(g_ptGPS.x + g_szGPS.cx, 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.cx = g_szMap.cy = 0; TCHAR s[4]; while(g_szMap.cx < 20 || g_szMap.cx > 200) { InputBox(s, 4, _T(“请输入地牢的宽度\n范围:20~200”), _T(“输入”), _T(“25”)); g_szMap.cx = _ttoi(s); } while(g_szMap.cy < 20 || g_szMap.cx > 200) { InputBox(s,4, _T(“请输入地牢的高度\n范围:20~200”), _T(“输入”), _T(“25”)); g_szMap.cy = _ttoi(s); } // 确保宽高为奇数 if (g_szMap.cx % 2 != 1) g_szMap.cx++; if (g_szMap.cy % 2 != 1) g_szMap.cy++; } // 生成地牢:初始化(注:宽高必须是奇数) void MakeMaze(int width, int height) { if (width % 2 != 1 || height % 2 != 1) return; int x, y; // 表述地牢体积,并分配地牢内存g_aryMap =new BYTE*[width + 2]; for(x = 0; x < width + 2; x++) { g_aryMap[x] = new BYTE[height + 2]; memset(g_aryMap[x], MAP_WALL, height +2); } // 表述边界 for (x = 0; x <= width + 1; x++) g_aryMap[x][0] = g_aryMap[x][height +1] = MAP_GROUND; for (y = 1; y <= height; y++) g_aryMap[0][y] = g_aryMap[width + 1][y] = MAP_GROUND;// 表述入口和出口 g_aryMap[1][2] = MAP_ENTRANCE; g_aryMap[width][height – 1] = MAP_EXIT; // 从任意点开始遍历生成地牢 TravelMaze(((rand() % (width – 1)) & 0xfffe) + 2, ((rand() % (height – 1)) & 0xfffe) + 2); // 将边界标记为地牢外 for (x = 0; x <= width + 1; x++) g_aryMap[x][0] = g_aryMap[x][height + 1] = MAP_OUTSIDE; for (y = 1; y <= height; y++) g_aryMap[0][y] = g_aryMap[width + 1][y] = MAP_OUTSIDE; } // 生成地牢:遍历 (x, y) 四周 void TravelMaze(int x, int y) { // 表述遍历方向 int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; // 将遍历方向乱序 int n, t, i; for(i = 0; i < 4; i++) { n = rand() % 4; t = d[i][0], d[i][0] = d[n][0], d[n][0] = t; t = d[i][1], d[i][1] = d[n][1], d[n][1] = t; } // 尝试周围四个方向 g_aryMap[x][y] = MAP_GROUND; for(i = 0; i < 4; i++) if (g_aryMap[x + 2 * d[i][0]][y + 2 * d[i][1]] == MAP_WALL) { g_aryMap[x + d[i][0]][y + d[i][1]] = MAP_GROUND; TravelMaze(x + d[i][0] * 2, y + d[i][1] * 2); // 递归 } } MAPITEMGetMazeItem(int x, int y) { return (MAPITEM)g_aryMap[x][y]; } // 绘制视野范围内的地牢 void Paint() { int x1, y1; // 绘制视野内的地牢 SetWorkingImage(&g_imgSight); for(int x = g_rtSight.left; x <= g_rtSight.right; x++) for(inty = g_rtSight.top; y <= g_rtSight.bottom; y++) { x1 = (x – g_rtSight.left) *20; y1 = (y – g_rtSight.top) *20; putimage(x1, y1, 20, 20, &g_imgItem, GetMazeItem(x, y), 0); } // 绘制格斗游戏者x1 = (g_ptPlayer.x – g_rtSight.left) *20; y1 = (g_ptPlayer.y – g_rtSight.top) * 20; putimage(x1, y1, 20,20, &g_imgItem, MAP_PLAYER, 0); // 绘制迷你世界地图 SetWorkingImage(&g_imgGPS); cleardevice(); int tx = (int)((g_ptPlayer.x –1) * g_szGPS.cx / (double)(g_szMap.cx – 1) + 0.5); int ty = (int)((g_ptPlayer.y – 1) * g_szGPS.cy / (double)(g_szMap.cy – 1) + 0.5); setlinecolor(YELLOW); circle(tx, ty, 1); // 更新到绘图窗口SetWorkingImage(); putimage(150, 110, 340, 260, &g_imgSight, 10, 10); putimage(g_ptGPS.x, g_ptGPS.y, &g_imgGPS); } int GetCmd() { int c = 0; if (GetAsyncKeyState(VK_LEFT) & 0x8000) c |= CMD_LEFT;if (GetAsyncKeyState(VK_RIGHT) & 0x8000) c |= CMD_RIGHT; if (GetAsyncKeyState(VK_UP) & 0x8000) c |= CMD_UP;if (GetAsyncKeyState(VK_DOWN) & 0x8000) c |= CMD_DOWN; if (GetAsyncKeyState(A) & 0x8000) c |= CMD_LEFT;if (GetAsyncKeyState(D) & 0x8000) c |= CMD_RIGHT; if (GetAsyncKeyState(W) & 0x8000) c |= CMD_UP; if(GetAsyncKeyState(S) & 0x8000) c |= CMD_DOWN; if (GetAsyncKeyState() & 0x8000) c |= CMD_MARKRED; if(GetAsyncKeyState(G) & 0x8000) c |= CMD_MARKGREEN; if (GetAsyncKeyState(Y) & 0x8000) c |= CMD_MARKYELLOW; if(GetAsyncKeyState(C) & 0x8000) c |= CMD_CLEARMARK; if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) c |= CMD_QUIT; return c; } // 处理用户输入的命令 void DispatchCmd(int cmd) { if (cmd & CMD_UP) OnUp(); if (cmd & CMD_DOWN) OnDown(); if(cmd & CMD_LEFT) OnLeft();if (cmd & CMD_RIGHT) OnRight(); if (cmd & CMD_MARKRED) OnMark(MAP_MARKRED); if(cmd & CMD_MARKGREEN) OnMark(MAP_MARKGREEN);if (cmd & CMD_MARKYELLOW) OnMark(MAP_MARKYELLOW); if(cmd & CMD_CLEARMARK) OnMark(MAP_GROUND); }// 向上移动 void OnUp() { if (g_ptPlayer.y > 1&& GetMazeItem(g_ptPlayer.x, g_ptPlayer.y –1) != MAP_WALL) { g_ptPlayer.y–; if (g_ptPlayer.y – g_rtSight.top < 4&& g_rtSight.top >0) { g_rtSight.top–; g_rtSight.bottom–; } } } // 向左移动 void OnLeft() { if (g_ptPlayer.x > 1 && GetMazeItem(g_ptPlayer.x – 1, g_ptPlayer.y) != MAP_WALL && GetMazeItem(g_ptPlayer.x –1, g_ptPlayer.y) != MAP_ENTRANCE) { g_ptPlayer.x–; if(g_ptPlayer.x – g_rtSight.left <5 && g_rtSight.left > 0) { g_rtSight.left–; g_rtSight.right–; } } } // 向右移动 void OnRight() { if (g_ptPlayer.x < g_szMap.cx && GetMazeItem(g_ptPlayer.x + 1, g_ptPlayer.y) != MAP_WALL) { g_ptPlayer.x++;if (g_rtSight.right – g_ptPlayer.x < 5&& g_rtSight.right <= g_szMap.cx) { g_rtSight.left++; g_rtSight.right++; } } }// 向下移动 void OnDown() { if(g_ptPlayer.y < g_szMap.cy && GetMazeItem(g_ptPlayer.x, 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(MAPITEM value) { g_aryMap[g_ptPlayer.x][g_ptPlayer.y] = value; }// 检查是否到出口 bool CheckWin() { if(g_ptPlayer.x == g_szMap.cx && g_ptPlayer.y == g_szMap.cy –1) { HWND hwnd = GetHWnd(); if (MessageBox(hwnd, _T(“恭喜你走出来了!\n您想再来一局吗?”), _T(“恭喜”), MB_YESNO | MB_ICONQUESTION) == IDYES) { InitGame(); return false; } else return true; }return false; } // 询问用户是否退出格斗游戏 bool Quit() { HWND hwnd = GetHWnd(); return(MessageBox(hwnd, _T(“您确定要退出格斗游戏吗?”), _T(“询问”), MB_OKCANCEL | MB_ICONQUESTION) == IDOK); }

大家赶紧去动手试试吧!

此外,我也给大家撷取我收集的其它资源,从最零此基础开始的教程到C词汇C++工程项目案例,帮助大家在学习C词汇的道路上披荆斩棘!

程式设计学习书籍撷取:

C语言零基础项目:迷宫游戏!详细思路+源码分享

程式设计学习视频撷取:

C语言零基础项目:迷宫游戏!详细思路+源码分享

整理撷取(多年学习的源标识符、工程项目实战视频、工程项目笔记,此基础入门教程)最重要的是你可以来一起交流提问程式设计问题哦!

对于C/C++感兴趣可以关注小编在后台私信我:【程式设计交流】一起来学习哦!

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务