C的第一个“大作业”——小游戏:没有推箱子的Helltaker
想了想还是发下这东西,太喜欢写注释了,虽然没啥营养内容,但还是希望新人轻松点。
极致偷懒不想用图形库,所以被批评简陋了
内容:没有推箱子的Helltaker(下附有推箱子的代码)
大概是三天赶作业的原因,所以没加推箱子逻辑,参考的只有推箱子绘制地图的方法(还不就是造点没用的轮子)
能看出的缺点太多,但是不太想完善了(画面音乐和把妹王差太多了)
不管怎么说吧,也是小成就了哈哈哈
有挺多没用的代码,为了凑要求的……见谅
/*没有推箱子的Helltaker 作者:chiha 游戏说明: 1、选择地图; 2、设置人物初始位置; 3、地图图标说明:★是钥匙,♀是操控人物,◎是出口; 4、操作方法: 大小写WASD或方向键控制移动; 大小写R重置所选地图的人物初始位置; 大小写Q退出游戏; ---函数库--- --初始目标-- 步数计数器 有 位置记录 有 移动键 有 人物输出&地图输出(图) 有 地图创建(包括入口和出口) 有 初始人物位置 有 --最终目标-- 地图选择 有 最优路径查找(限制步数) 无 钥匙设置 有 添加音乐 无 -新想法- 限制只能用小写awsdqr(加入ctype.h中的识别函数islower()) */ // #include #include #include #include //getch() #include //Sleep() #include #define MAX 10 typedef int Key; typedef struct Position{ int x,y; }POS; typedef struct MAP{ int x[MAX][MAX]; }map; //int next[4][2]={(1,0),()} 如果采用小括号赋值,括号整体的值是最后一个元素的值 int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; //移动坐标 int cnt = 0; //步数计数 POS Origin; //人物原始位置 //地图库 map Maplib_1 = { 1,1,1,1,1,1,1,1,1,1, 1,0,0,1,0,1,0,0,0,1, 1,0,0,1,0,0,0,0,0,1, 1,0,0,0,1,0,1,0,0,1, 1,0,0,0,0,0,0,1,0,1, 1,1,1,0,1,1,1,0,0,1, 1,0,0,0,0,0,0,1,0,5, 1,0,1,1,0,1,0,0,0,1, 1,0,1,0,0,1,0,1,1,1, 3,0,0,0,1,1,1,1,1,1};//10行10列 map Maplib_2 = { 1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,1, 1,0,1,1,0,1,1,1,0,1, 1,0,0,3,1,0,1,0,0,1, 1,0,1,0,0,0,0,1,0,1, 1,0,1,0,1,1,1,1,0,1, 1,0,1,0,0,1,0,1,0,5, 1,0,0,0,0,0,0,1,0,1, 1,0,1,0,0,1,0,0,0,1, 1,1,0,1,1,1,1,1,1,1}; int move_Ctrl(POS &A, map M); //移动控制 int move_Judge(POS A,map M); //移动判断 判断人物是否与地图障碍重叠 返回值为 1重叠 0正常 void create_Map(map &M); //创建地图 int M[][10] int只存地址 (全局变量map实现,无法换地图) void init_Pos(POS &A, map M); //初始位置 手动输入xy int pace_Count(int &c); //步数记录 全局变量cnt实现 int output_Cha(POS A,map M); //人物输出 修改地图来实现 int key_exit(POS A,map M,Key &k,int c);//钥匙设置 int key_Delete(map &M, POS A); //在地图上删除钥匙的位置 void game_WIN(int c); //游戏结束 void game_load(); //游戏加载模拟 void game_intr(); //游戏介绍 int map_Select(map &M); //地图选择 void map_Show(map M1,map M2); //地图展示 int main(){ map Map; //地图地址 POS pos; //人物位置 Key k = 0; //钥匙是否获取flag int move_Status = 0; game_intr(); map_Show(Maplib_1,Maplib_2); map_Select(Map); init_Pos(pos,Map); game_load(); //create_Map(Map); do{ system("cls"); //刷新屏幕 key_exit(pos,Map,k,cnt); //1111 output_Cha(pos, Map); move_Status = move_Ctrl(pos,Map); key_exit(pos,Map,k,cnt); //2222必须两遍,否则会无法结束游戏 key_Delete(Map, pos); if(move_Status != 7) //加了这句if步数正常了,不用再/2处理 pace_Count(cnt); }while(1); return 0; } void game_intr(){ printf("游戏说明:\n1、选择地图;\n2、设置人物初始位置;\n3、地图图标说明:★是钥匙,♀是操控人物,◎是出口;\n4、操作方法:\n大小写WASD或方向键控制移动;\n大小写R重置所选地图的人物初始位置;\n大小写Q退出游戏;\n"); } int key_Delete(map &M, POS A){ if(M.x[A.x][A.y] == 3) M.x[A.x][A.y] = 0; return 0; } void game_load(){ system("cls");printf("正在生成所选地图");Sleep(500);printf("."); Sleep(500);printf(".");Sleep(500);printf(".");Sleep(500); system("cls");printf("正在加载人物");Sleep(500);printf("."); Sleep(500);printf(".");Sleep(500);printf(".");Sleep(500); } void map_Show(map Maplib_1,map Maplib_2){ for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ switch (Maplib_1.x[i][j]) { case 0: printf(" "); //空白的地方 break; case 1: printf("■"); //墙 break; case 3: printf("★"); //钥匙 break; case 5: printf("◎"); //出口 break; } } printf("\n"); } printf("地图1\n\n"); for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ switch (Maplib_2.x[i][j]) { case 0: printf(" "); //空白的地方 break; case 1: printf("■"); //墙 break; case 3: printf("★"); //钥匙 break; case 5: printf("◎"); //出口 break; } } printf("\n"); } printf("地图2\n\n"); } int map_Select(map &M){ int n; printf("地图选择"); sss:printf("(可选1,2):");//sss scanf("%d",&n); printf("\n"); switch (n) { case 1: M=Maplib_1; printf("你选择了我,我是いちぽ哒!\n"); break; case 2: M=Maplib_2; printf("你选择了我,我是にぽ哒!\n"); break; default: printf("我没有那么厉害啦!!!\n"); printf("重新选咯~"); // map_Select(M); //递归不好实现,改用goto goto sss; } return 0; } void game_WIN(int c){ int n; system("cls"); printf("成功\n"); printf("花费步数:%d\n",c);//计数会计数两遍,暂时作/2处理 printf("按R重置游戏,按Q退出游戏\n"); } int key_exit(POS A,map M,Key &k,int c){ if(M.x[A.x][A.y] == 3) k = 1; //拿到钥匙 if(k == 1 && M.x[A.x][A.y] == 5) game_WIN(c); //拿到钥匙且走到出口 return 0; } int move_Ctrl(POS &A,map M){ int dir;//方向键 // Origin_CG = A;//保留上一步 dir = getch();//getchar()需要回车 // if(islower(dir)||dir==75||dir==72||dir==77||dir==80)//加这句只限制小写后,用方向键操作会加倍步数 switch (dir){ //case 'A': case 'a': case 75: //左 A.y--; //数组反向思维 if(move_Judge(A,M)==1) A.y++; //重叠就重新输入 break; //case 'W': case 'w': case 72: //上 A.x--; if(move_Judge(A,M)==1) A.x++; break; //case 'D': case 'd': case 77: //右 A.y++; if(move_Judge(A,M)==1) A.y--; break; //case 'S': case 's': case 80: //下 A.x++; if(move_Judge(A,M)==1) A.x--; break; //case 'R': case 'r': A = Origin; //cnt = -1; //因为main执行后会加一所以需要改为-1 cnt = 0; //或者和退出Q一样用返回值7 return 7; //case 'Q': case 'q': Sleep(1000); //慢一点退出 exit(-2); default: //exit(-2); //测试暂定直接退出 return 7; //7的意志!!! } return 0; } void init_Pos(POS &A,map M){ printf("\n请输入人物的初始位置: x = "); scanf("%d",&A.y); printf("%23sy = ");//刚刚好对齐 scanf("%d",&A.x); A.y--; A.x--; Origin = A; if(A.y > 9 || A.x > 9 || move_Judge(A, M)){ //人物是否生成越界或者与地图重叠 printf("你不能出现在这!!!\n"); init_Pos(A,M); } } int move_Judge(POS A,map M){ if(M.x[A.x][A.y]==1) return 1; //重叠地图 1 return 0; //正常 0 } int pace_Count(int &c){ c++; return 0; } int output_Cha(POS A,map M){ M.x[A.x][A.y] = 2; //把人放到地图上先————先前已经判断重叠,这里直接放 for(int i = 0; i < 10; i++){ for(int j = 0; j < 10; j++){ switch (M.x[i][j]) { case 0: printf(" "); //空白的地方 break; case 1: printf("■"); //墙 break; case 2: printf("♀"); //人 break; case 3: printf("★"); //钥匙 break; case 5: printf("◎"); //出口 break; default: break; } if(i==6 && j==9) printf(" 已走步数:%d",cnt); if(i==7 && j==9) printf(" 按R重新开始"); } printf("\n"); } return 0; }
以下是推箱子的,实在找不到原作者了,实在抱歉。。。(作为轮子来说应该也没太大关系)
#include<stdio.h> #include<conio.h> #include<windows.h> int map[9][11]={ {0,1,1,1,1,1,1,1,1,1,0}, {0,1,0,0,0,1,0,0,0,1,0}, {0,1,0,0,3,0,0,0,0,1,0}, {0,1,0,3,0,3,3,3,0,1,1}, {0,1,0,0,0,2,0,0,0,0,1}, {1,1,0,0,1,1,1,0,3,0,1}, {1,0,4,4,0,4,0,0,0,0,1}, {1,0,4,4,0,4,4,3,0,1,1}, {1,1,1,1,1,1,1,1,1,1,0} };//原始的图表,五行六列,其中 0 代表着空白的地方; 1 代表着墙;2 代表着人; //3 代表着箱子;4 代表着箱子的终点位置。 //图的变化要靠自己来编写数组,通过数字来进行图的构造。 int drawmain(); int tuidong(); int winshu(); int main()//主函数 { while(1) { system("cls");//对其进行清屏 drawmain(); tuidong(); } printf("shuchu \n"); return 0; } //把图形刻画出来 int drawmain() { int i,j; winshu();//调用输赢的函数 for(i=0;i<9;i++) { for(j=0;j<11;j++) { switch(map[i][j]) { case 0: printf(" "); //空白的地方 break; case 1: printf("■"); //墙 break; case 2: printf("♀"); //人 break; case 3: printf("☆"); //箱子 break; case 4: printf("◎"); //终点地方 break; case 6: printf("♂");//人加终点位置 break; case 7: printf("★") ;//箱子加终点位置 break; } } printf("\n"); } } //进行小人的移动,整个移动的过程就是数组变化的过程 int tuidong() { int count,caw=0;//行和列 int i,j,tui; for(i=0;i<9;i++){ for (j=0;j<11;j++) { if(map[i][j]==2||map[i][j]==6) { count=i; caw=j; } } } tui=getch();//与getchar()有区别的是:getchar()输入一个字符后需要回车来进行下一个字符的输入, //比较麻烦 ,getch()则不需要回车就能连续输入多个字符。 switch(tui) {//上 case 'W': case 72: // 1.人的前面是空地; // 2.人的前面是终点位置; // 3.人的前面是箱子 //3.1.箱子的前面是空地; //3.2.箱子的前面是终点位置。 if(map[count-1][caw]==0||map[count-1][caw]==4) { map[count][caw]-=2; map[count-1][caw]+=2; } else if(map[count-1][caw]==3||map[count-1][caw]==7) { if(map[count-2][caw]==0||map[count-2][caw]==4) { map[count][caw]-=2; map[count-1][caw]-=1; map[count-2][caw]+=3; } } break; //下 case 'S': case 80://键值 if(map[count+1][caw]==0||map[count+1][caw]==4) { map[count][caw]-=2; map[count+1][caw]+=2; } else if(map[count+2][caw]==0||map[count+2][caw]==4) { if(map[count+1][caw]==3||map[count+1][caw]==7) { map[count][caw]-=2; map[count+1][caw]-=1; map[count+2][caw]+=3; } } break; //左 case 'A': case 75: if(map[count][caw-1]==0||map[count][caw-1]==4) { map[count][caw]-=2; map[count][caw-1]+=2; } else if(map[count][caw-2]==0||map[count][caw-2]==4) { if(map[count][caw-1]==3||map[count][caw-1]==7) { map[count][caw]-=2; map[count][caw-1]-=1; map[count][caw-2]+=3; } } break; //右 case 'D': case 77: if(map[count][caw+1]==0||map[count][caw+1]==4) { map[count][caw]-=2; map[count][caw+1]+=2; } else if(map[count][caw+2]==0||map[count][caw+2]==4) { if(map[count][caw+1]==3||map[count][caw+1]==7) { map[count][caw]-=2; map[count][caw+1]-=1; map[count][caw+2]+=3; } } break; } } int winshu() { int k = 0;//初始化 int j,i; for(i=0;i<9;i++) { for (j=0;j<11;j++) { if(map[i][j]==3) k++; } } if(k==0) printf("恭喜你,你赢了!\n"); }
共勉