【c语言】迷宫游戏

您所在的位置:网站首页 迷宫迷宫怎么画 【c语言】迷宫游戏

【c语言】迷宫游戏

2024-06-21 05:30| 来源: 网络整理| 查看: 265

之前想写的迷宫游戏今天终于大功告成,解决了随机生成迷宫地图的问题,使用的是深度优先算法递归版本,之前的迷宫找通路问题用的是深度优先算法的非递归实现.之前写过推箱子,推箱子用到了人物的移动,以及碰到墙就不会走,我们可以稍微变一下就变成了迷宫游戏

1.游戏演示

迷宫演示

2.游戏整体思路

1.迷宫的生成(难点) 2.人物的移动 3.走到出口的判定 4.使用图形库添加人物图片,墙,路的图片

3.预备准备

将每个状态用数字表示,则创建一个枚举类型,以及定义地图的高和宽

#define Height 9 #define Width 9 enum Mine { Road, Wall, Start, End, Player };

由枚举类型可知,Road(路)为0,Wall(墙)为1,Start(起点)为2,End(终点)为3,Player(玩家)为4,初始化地图大小为9*9;

int map[Height+2][Width+2]; int flag = 0;

定义一个二维数组大小为11*11;

4.迷宫的初始化

迷宫的创建

void create_map(int x, int y) { int c[4][2] = { 0,1,1,0,0,-1,-1,0 }; int i, j, t; for (i = 0; i if (map[x + 2 * c[i][0]][y + 2 * c[i][1]] == Wall) { map[x + c[i][0]][y + c[i][1]] = Road; create_map(x + 2 * c[i][0], y + 2 * c[i][1]); } } } void init() { for (int i = 0; i if (i == 0 || i == Height + 1 || j == 0 || j == Width + 1) map[i][j] = Road; else map[i][j] = Wall; } } create_map(2 * (rand() % (Height / 2) + 1), 2 * (rand() % (Width / 2) + 1)); for (int i = 0; i map[0][j] = Wall; map[Height + 1][j] = Wall; } map[2][1] = Start+Player; map[Height - 1][Width] = End; } 5.键盘控制人物移动

这里推箱子那节有讲,稍微改变一下即可

void keyevent() { int i = 0; int j = 0; for (i = 1; i if (map[i][j] == Player|| map[i][j] == Player +Start|| map[i][j] == Player +End)//,遍历二维数组,如果二维数组某个元素为4,6,7的话直接跳出两个循环, { goto end; } } } end:;//获取当前人物坐标 char ch = _getch(); //printf("%d %c", ch, ch);//w 119 a 97 s 115 d 100 switch (ch) { case 119: case 'w ': case 'W': if (map[i - 1][j] == Road|| map[i - 1][j]== End|| map[i - 1][j] ==Start)//当人物当前位置上面是路或者出口或者入口都可以走 { map[i - 1][j] += Player;//移动后的位置+4,表示玩家出现在此坐标 map[i][j] -= Player;//起始位置-4,表示玩家消失在此坐标 } break; case 97: case 'a ': case'A': if (map[i][j - 1]== Road || map[i][j - 1] == End || map[i][j - 1] ==Start) { map[i][j - 1] += Player; map[i][j] -= Player; } break; case 115: case 's ': case'S': if (map[i + 1][j] == Road || map[i + 1][j] == End|| map[i + 1][j] == Start) { map[i + 1][j] += Player; map[i][j] -= Player; } break; case 100: case 'd ': case'D': if (map[i][j + 1] == Road || map[i][j + 1] == End|| map[i][j + 1]==Start) { map[i][j + 1] += Player; map[i][j] -= Player; } break; } for (i = 1; i if (map[i][j] == Player || map[i][j] == Player + Start || map[i][j] == Player + End) { goto end1; } } } end1:;//移动后找到玩家当前位置 } 6.打印地图函数 void gamedraw() { for (int i = 1; i switch (map[i][j]) {case Road: printf(" "); //路 //一个中文字符相当于二个英文字符 break; case Wall: printf("■");//墙 break; case Start: printf("入");//入口 break; case End: printf("出");//出口 break; case Player: printf("♂");//玩家 break; case Player+ Start: printf("♂");//玩家在起点 break; case Player +End://玩家在终点 printf("♂"); break; } } printf("\n"); } } 7.判断到出口函数 void iswin() { if (map[Height - 1][Width]==Player+End) { flag = 1; } }

如果终点的坐标map[Height - 1][Width]7,说明玩家到终点,将flag置为1; 然后 在主函数中加个判断语句,如果flag1,退出 程序

8.主函数 int main() { srand((unsigned)time(NULL)); init();//初始化地图 //initgraph(Height * 40, Width * 40); //bgm(); //loadimg(); while (1) { gamedraw();//画地图函数 keyevent();//获取方向函数 iswin();//判断是否到终点 if (flag == 1) { exit(-1);//到了退出程序 } system("cls");//清屏函数,如果不知道为什么加这一步的话,你可以先不加试试 } getchar(); return 0; } 9.不加图形库的话的头文件 #include #include//time的头文件 #include //srand的头文件 #include //-getch()头文件 #include //清屏函数头文件 10.不加图形库游戏源码 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #define Height 9 #define Width 9 enum Mine { Road, Wall, Start, End, Player }; int map[Height+2][Width+2]; int flag = 0; void iswin() { if (map[Height - 1][Width]==Player+End) { flag = 1; } } void gamedraw() { for (int i = 1; i switch (map[i][j]) {case Road: printf(" "); //一个中文字符相当于二个英文字符 break; case Wall: printf("■"); break; case Start: printf("入"); break; case End: printf("出"); break; case Player: printf("♂"); break; case Player+ Start: printf("♂"); break; case Player +End: printf("♂"); break; } } printf("\n"); } } void keyevent() { int i = 0; int j = 0; for (i = 1; i if (map[i][j] == Player|| map[i][j] == Player +Start|| map[i][j] == Player +End) { goto end; } } } end:; char ch = _getch(); //printf("%d %c", ch, ch);//w 119 a 97 s 115 d 100 switch (ch) { case 119: case 'w ': case 'W': if (map[i - 1][j] == Road|| map[i - 1][j]== End|| map[i - 1][j] ==Start) { map[i - 1][j] += Player; map[i][j] -= Player; } break; case 97: case 'a ': case'A': if (map[i][j - 1]== Road || map[i][j - 1] == End || map[i][j - 1] ==Start) { map[i][j - 1] += Player; map[i][j] -= Player; } break; case 115: case 's ': case'S': if (map[i + 1][j] == Road || map[i + 1][j] == End|| map[i + 1][j] == Start) { map[i + 1][j] += Player; map[i][j] -= Player; } break; case 100: case 'd ': case'D': if (map[i][j + 1] == Road || map[i][j + 1] == End|| map[i][j + 1]==Start) { map[i][j + 1] += Player; map[i][j] -= Player; } break; } for (i = 1; i if (map[i][j] == Player || map[i][j] == Player + Start || map[i][j] == Player + End) { goto end1; } } } end1:; } void create_map(int x, int y) {//8,8 int c[4][2] = { 0,1,1,0,0,-1,-1,0 }; int i, j, t; for (i = 0; i if (map[x + 2 * c[i][0]][y + 2 * c[i][1]] == Wall) { map[x + c[i][0]][y + c[i][1]] = Road; create_map(x + 2 * c[i][0], y + 2 * c[i][1]); } } } void init() { for (int i = 0; i if (i == 0 || i == Height + 1 || j == 0 || j == Width + 1) map[i][j] = Road; else map[i][j] = Wall; } } create_map(2 * (rand() % (Height / 2) + 1), 2 * (rand() % (Width / 2) + 1)); for (int i = 0; i map[0][j] = Wall; map[Height + 1][j] = Wall; } map[2][1] = Start+Player; map[Height - 1][Width] = End; } int main() { srand((unsigned)time(NULL)); init(); //initgraph(Height * 40, Width * 40); //bgm(); //loadimg(); while (1) { gamedraw(); keyevent(); iswin(); if (flag == 1) { exit(-1); } system("cls"); } getchar(); return 0; } 11.加图形库版本 12.头文件改变 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include //图形库头文件 #include//包含多媒体设备接口头文件 #pragma comment(lib,"winmm.lib")//加载静态库 13.加载图片

这里将游戏的素材,墙,玩家,路,起点,终点的图片放到.cpp的统一目录下,这里可以去看一下我写的推箱子.

void loadimg() { for (int i = 0; i for (int i =1; i int x = (j-1)* 40; int y = (i-1) * 40; switch (map[i][j]) { case Road: putimage(x, y, ima_all); //一个中文字符相当于二个英文字符 break; case Wall: putimage(x, y, ima_all + 1); break; case Player: putimage(x, y, ima_all+4); break; case Player +Start: putimage(x, y, ima_all+4); break; case Start: putimage(x, y, ima_all+2); break; case End: putimage(x, y, ima_all+3); break; case Player+End: putimage(x, y, ima_all+4); break; } } } }

具体说一下为什么这里的int x = (j-1)* 40;int y = (i-1) * 40;x,y表示要贴的图片的左上角贴在游戏的哪个位置,因为二维数组是将1,1的坐标贴在界面的左上角,界面的左上角坐标就是0,0.x表示行,y表示列.

15.主函数的修改 int main() { srand((unsigned)time(NULL)); init(); initgraph(Height * 40, Width * 40); //bgm(); loadimg(); while (1) { gamedraw(); keyevent(); iswin(); if (flag == 1) { exit(-1); } system("cls"); } getchar(); return 0; } 16.加图形库的程序源码 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include //#include//包含多媒体设备接口头文件 //#pragma comment(lib,"winmm.lib")//加载静态库 #define Height 9 //如果要修改难度可以修改这里,必须是奇数 #define Width 9 //如果要修改难度可以修改这里,必须是奇数 enum Mine { Road, Wall, Start, End, Player }; int map[Height+2][Width+2]; int flag = 0; IMAGE ima_all[5]; //void bgm() //{ //打开音乐 // mciSendString("open ./music.MP3", 0, 0, 0);//后面参数不用管 //播放音乐 // mciSendString("play ./music.MP3", 0, 0, 0);//后面参数不用管 //} void loadimg() { for (int i = 0; i if (map[Height - 1][Width]==Player+End) { flag = 1; } } void gamedraw() { for (int i =1; i int x = (j-1)* 40;//修改难度时将图片大小放成10,地图才能放得下*40改为*10 int y = (i-1) * 40;//修改难度时将图片大小放成10,地图才能放得下*40改为*10 switch (map[i][j]) { case Road: putimage(x, y, ima_all); break; case Wall: putimage(x, y, ima_all + 1); break; case Player: putimage(x, y, ima_all+4); break; case Player +Start: putimage(x, y, ima_all+4); break; case Start: putimage(x, y, ima_all+2); break; case End: putimage(x, y, ima_all+3); break; case Player+End: putimage(x, y, ima_all+4); break; } } } } void keyevent() { int i = 0; int j = 0; for (i = 1; i if (map[i][j] == Player|| map[i][j] == Player +Start|| map[i][j] == Player +End) { goto end; } } } end:; char ch = _getch(); //printf("%d %c", ch, ch);//w 119 a 97 s 115 d 100 switch (ch) { case 119: case 'w ': case 'W': if (map[i - 1][j] == Road|| map[i - 1][j]== End|| map[i - 1][j] ==Start) { map[i - 1][j] += Player; map[i][j] -= Player; } break; case 97: case 'a ': case'A': if (map[i][j - 1]== Road || map[i][j - 1] == End || map[i][j - 1] ==Start) { map[i][j - 1] += Player; map[i][j] -= Player; } break; case 115: case 's ': case'S': if (map[i + 1][j] == Road || map[i + 1][j] == End|| map[i + 1][j] == Start) { map[i + 1][j] += Player; map[i][j] -= Player; } break; case 100: case 'd ': case'D': if (map[i][j + 1] == Road || map[i][j + 1] == End|| map[i][j + 1]==Start) { map[i][j + 1] += Player; map[i][j] -= Player; } break; } for (i = 1; i if (map[i][j] == Player || map[i][j] == Player + Start || map[i][j] == Player + End) { goto end1; } } } end1:; } void create_map(int x, int y) {//8,8 int c[4][2] = { 0,1,1,0,0,-1,-1,0 }; int i, j, t; for (i = 0; i if (map[x + 2 * c[i][0]][y + 2 * c[i][1]] == Wall) { map[x + c[i][0]][y + c[i][1]] = Road; create_map(x + 2 * c[i][0], y + 2 * c[i][1]); } } } void init() { for (int i = 0; i if (i == 0 || i == Height + 1 || j == 0 || j == Width + 1) map[i][j] = Road; else map[i][j] = Wall; } } create_map(2 * (rand() % (Height / 2) + 1), 2 * (rand() % (Width / 2) + 1)); for (int i = 0; i map[0][j] = Wall; map[Height + 1][j] = Wall; } map[2][1] = Start+Player; map[Height - 1][Width] = End; } int main() { srand((unsigned)time(NULL)); init(); initgraph(Height * 40, Width * 40); //bgm();这个音乐也不加了 loadimg(); while (1) { gamedraw(); keyevent(); iswin(); if (flag == 1) { exit(-1); } //system("cls");这里不需要,因为用不到控制台 } getchar(); return 0; }

注意不用图形库的铁铁们可以直接复制10.不加图形库的程序源码可以直接运行的 这里给大家推荐一个电影心迷宫巨巨巨巨巨好看,直接点题,真有我小汁的 请添加图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3