每天一个c语言小项目,提升你的编程能力!
迷宫游戏其实有很多种类型,比如说营救公主的一款,又比如说闯关的一款,其他的一些种类这里就不一一列举了。但是不管哪一款迷宫游戏,唯一不变的就是迷宫的实现这一核心功能,每一款迷宫游戏无非就是根据自己的游戏性质在迷宫之中添加一些必要的元素罢了。
我们今天的主要目标就是用c语言来实现迷宫的原本功能,纯天然无污染,没有添加任何防腐剂(因为没有其他的花里胡哨的功能)
上面就是咱们的效果图预览,以图形库easyx来搭配c语言语法实现的迷宫界面,然后也实现了例如一些按键操作,边界检测这样的功能,整体来说还是比较完善的。
本项目编译环境:visual studio 2019/2022,easyx插件
代码展示:
#include #include #include //////////////////////////////////////////////////////// 定义全局变量//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 };// 枚举用户的控制命令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 };//////////////////////////////////////////////////////// 函数声明//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), 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*)x20x20x20xffx04x04x04xff); 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*)x50x55x22x20x05x55x22x02); solidrectangle(0, 0, 19, 19); // 恢复坐标系 setorigin(0, 0); // 显示作者 setworkingimage(); settextcolor(blue); tchar author[] = _t(powered by zhaoh1987@qq.com); outtextxy(471, 4, author); settextcolor(lightblue); outtextxy(470, 3, author);}// 初始化游戏数据void initgame(){ // 提示用户输入迷宫大小 getmazesize(); // 初始化参数 if (g_arymap != null) { // 清理迷宫地图占用的内存 for(int x = 0; x 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 200) { inputbox(s, 4, _t(请输入迷宫的宽度范围:20~200), _t(输入), _t(25)); g_szmap.cx = _ttoi(s); } while(g_szmap.cy 200) { inputbox(s, 4, _t(请输入迷宫的高度范围: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); // 递归 }}// 获取指定坐标的迷宫元素mapitem getmazeitem(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 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 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(恭喜你走出来了!您想再来一局吗?), _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);}
大家赶紧去动手试试吧!
世界屋脊之上,华为助力中广核打造高海拔电站标杆
智能手表 何时才能牵动你的心弦?
谷歌地图充电站搜索功能,充电标准不统一也不怕
RAID磁盘阵列的DIY使用方法和基础知识
搭建ftp服务器的步骤
C语言零基础项目:迷宫游戏!详细思路+源码分享
特斯拉在中国大陆的超级充电站达到700座
氩弧焊机不打火怎样修_氩弧焊机安全操作规程
SMT工厂转型做PCBA加工的难题
如何设计一个共源级放大电路
互联网医疗将迎来医疗行业的新机遇
芯片巨头高通宣布其首款超声波指纹读取器发布
中芯国际第二代FinFET工艺进入小批量试产
iPhone8什么时候上市?iphone8最新消息:iphone 8发布会时间确定,还有五大新特性,售价超1000刀买不买?
人工智能聊天机器人的发展将成为未来市场的趋势
2020年广电5G将会正式商用
SMT贴片加工出现炸锡现象怎么办?
浪潮推出基于异构虚拟化的入门级存储
缺货?缺货?缺货?2018年MLCC市场走向究竟如何
乐和游戏推出结合游戏的 3D 电子贺卡