失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言双人贪吃蛇

C语言双人贪吃蛇

时间:2022-06-22 00:52:39

相关推荐

C语言双人贪吃蛇

其实我写的博客,主要还是给自己看的吧,让自己随时随地可以查阅。不都说,这篇是贪吃蛇的。希望能给看到的萌新小伙伴一点启发吧,也欢迎大佬指点。

贪吃蛇主要有以下几个问题:

1.地图如何产生?

2.蛇如何画?蛇尾巴如何在每次吃到食物的时候自增一格?蛇的移动如何实现?

3.如何判定蛇的状态,即吃到食物还是撞到障碍物?

1.对于第一个问题,实际上比较容易解决,就是利用一个二维数组,通过不同的值来打印出不同的图案。比如一个3*2的二维数组,1 1 1

1 0 1

1 1 1 然后再值是1 的地方打印#,在值是0的地方打印空格。这就可以实现地图的绘制。利用不同的数字来代表不同的属性。

2.

蛇如何画?先来看一条蛇 @ 3,6

@ 3,7

@ 3,8

@ 从上到下,坐标分别是 3,9 我们发现,一个蛇也可以用数组来显示,数组定义二维的,存储横纵坐标。 但是,千万不要漏掉了蛇的长度。之后会讲到。

如何画蛇?通过上诉坐标,实际上只需要gotoxy(3,6);然后printf("@");其他的几个蛇身也是这样画出来。那么这里遇到一个问题,利用一个for循环就可以,但是循环多少次呢?这里就要用到一个变量来存储蛇的长度*****

会画蛇了以后还要会让蛇移动,这里举个例子向右移动,还是上例蛇

@@ 3,6 4,6

@ 3,7

@ 3,8 可以看到,原来第一个坐标3,6变成第二个的坐标,原来第二个坐标3,7变成第三个坐标。 把坐标往后移位就可以实现新的蛇坐标。 蛇头的坐标需要相应的改变,这个简单不多说

做到这一步,蛇移动已经差不多了,但是会发现,蛇的尾巴画出来的@还存在,为了消去这个蛇尾,可以在蛇的尾部打上空格来覆盖掉这个蛇尾。 但是,聪明的小伙伴已经想到了,如果吃了东西,其实会边长一格,那么这个变长的蛇格就是原来的蛇尾,那么这时候又要打印出蛇尾的@ 说了这么多,是不是已经知道需要把蛇尾坐标单独存储了呀

3.判定蛇的状态,这个就是利用蛇头坐标是不是在食物,比如蛇头转向以后坐标是4,6那么可以看看二维数组坐标对应的6行4列是不是金币属性还是障碍物属性等等。根据不同的就可以进行不同的操作。

然后,到这里基本上就没有什么问题了吧,下面附上源代码。是双人贪吃蛇,代码很杂乱,不适合阅读,而且因为是两只蛇,有的地方可以更简略一些我也懒得改了。还做了一点改变颜色的什么的,还有自己做了一点简略的菜单加上,emmmmm瞎搞的玩意。目前模式1还没有做,单人和双人的操作都可以。代码是真的很乱,自己都不怎么想去整改了,核心思想都写上面了,希望可以帮助到有需之人吧。

#include<stdio.h>#include<windows.h>#include<time.h>#include<conio.h>#include<string.h>#include<math.h>#include<stdlib.h>#define H 20#define L 80 //H high高度 L long长度#define UP 0#define DOWN 1#define LEft 2#define RIGHT 3#define mmlong 3 //这是蛇长 //蛇1 int map[H][L] ={0}; //地图,H行,L列int snake[1000][2] = {0};//蛇,0列代表x坐标,1列代表y坐标 int snake_long = mmlong; //蛇初始长度4个int direction = UP; //蛇头方向,初始向上 int tail[2]={0};//寄存蛇尾int speed = 300,game_in = 3; //控制蛇速度int score = 0; //蛇1分数 //蛇2int snake_2[1000][2] = {0};//蛇,0列代表x坐标,1列代表y坐标 int snake_long_2 = mmlong; //蛇初始长度4个int direction2 = UP; //蛇头方向,初始向上 int tail_2[2]={0};//寄存蛇尾int speed_2 = 300;//控制蛇速度int score_2 = 0; //蛇2分数//通用int target = 0,time_game = 0; //time_game 游戏对于模式 void gotoxy(int i,int j) //移动光标{COORD position={i,j};SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);}void color(int x) //改变输出颜色 {if( x>= 0 && x<= 15) //参数在0-15的范围颜色{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);//只有一个参数x,改变字体颜色}else//默认的颜色白色{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);}}void product_map() //地图数据初始化 {int i,j,c = 0;snake_long = snake_long_2 = mmlong; //蛇初始4长度speed = speed_2 = 300; //蛇速度初始300score = score_2 = 0;//初始分数初始化0 emd:c++;srand(time(NULL)+c*100);direction = rand()%4; //给蛇1一个随机方向,但不能向下 if(direction == 1)goto emd; hmd:c++;srand(time(NULL)+c*100);direction2 = rand()%4; //给蛇2一个随机方向,但不能向下 if(direction2 == 1)goto hmd;for(i = 0;i<H;i++){for(j = 0;j<L;j++){map[i][j] = 0; //每次开始新游戏,需要重新给二维数组赋值0 }} for(i = 0;i<H;i++){map[i][0] = map[i][L-1] = 1;}for(i = 0;i<L;i++){map[0][i] = map[H-1][i] = 1;}snake[0][0] = L/4;snake[0][1] = H/4; //蛇头初始坐标在中心snake_2[0][0] = L*3/4;snake_2[0][1] = H*3/4; //蛇头初始坐标在中心for(i = 1;i<mmlong;i++){snake[i][0] = snake[0][0];snake[i][1] = snake[0][1] + i; //蛇1身坐标,竖直向下3个snake_2[i][0] = snake_2[0][0];snake_2[i][1] = snake_2[0][1] + i; //蛇2身坐标,竖直向下3个 }tail[0] = snake[3][0];tail[1] = snake[3][1];tail_2[0] = snake_2[3][0];tail_2[1] = snake_2[3][1]; }void money_product() //产生金钱{int i,j,k,x,y; //x,y是金币的数组下标寄存器 for(i = 0,k = 1;;){cmd:k++;srand(time(NULL)+k*20+(j-2)*30);x = rand()%(L-2) + 1;y = rand()%(H-2) + 1;for(j = 0;j<snake_long;j++) //防止产生在蛇1身上 {if(x == snake[j][0] && y == snake[j][1])goto cmd; //重新产生 }for(j = 0;j<snake_long_2;j++) //防止产生在蛇2身上 {if(x == snake_2[j][0] && y == snake_2[j][1])goto cmd; //重新产生 }if(map[y][x] != 2) //已经是金钱不再累计 {map[y][x] = 2;i++;}if(i == 7)break; } } void draw_map() //画地图 {int i,j;gotoxy(0,0);for(i = 0;i<H;i++){for(j = 0;j<L;j++){if(map[i][j] == 1){color(12);printf("#");}else if(map[i][j] == 0){printf(" ");}else if(map[i][j] == 2){color(6);printf("*");}}printf("\n"); }}void draw_snake() //画蛇{int i;color(4);gotoxy(snake[0][0],snake[0][1]);printf("@");color(14);for(i = 1;i<snake_long;i++){gotoxy(snake[i][0],snake[i][1]);printf("@");}}void draw_snake2() //画蛇2 {int i;color(1);gotoxy(snake_2[0][0],snake_2[0][1]);printf("@");color(9);for(i = 1;i<snake_long_2;i++){gotoxy(snake_2[i][0],snake_2[i][1]);printf("@");}} void move_snake() //蛇1身移动{int i;tail[0] = snake[snake_long-1][0];tail[1] = snake[snake_long-1][1]; //寄存蛇尾 gotoxy(snake[snake_long-1][0],snake[snake_long-1][1]);printf(" "); //把蛇尾画空格for(i = snake_long-1;i>0;i--) //后移赋值 把后一个等于前一个的坐标,实现移动 {snake[i][0] = snake[i-1][0];snake[i][1] = snake[i-1][1];}}void move_snake2() //蛇2身移动{int i;tail_2[0] = snake_2[snake_long-1][0];tail_2[1] = snake_2[snake_long-1][1]; //寄存蛇尾 gotoxy(snake_2[snake_long_2-1][0],snake_2[snake_long_2-1][1]);printf(" "); //把蛇尾画空格for(i = snake_long_2-1;i>0;i--) //后移赋值 把后一个等于前一个的坐标,实现移动 {snake_2[i][0] = snake_2[i-1][0];snake_2[i][1] = snake_2[i-1][1];}}void move_snake_head() //蛇1头移动{switch(direction){case 0:snake[0][1]--;break;//向上 case 1:snake[0][1]++;break;//向下 case 2:snake[0][0]--;break;//向左 case 3:snake[0][0]++;break;//向右 }}void move_snake_head2() //蛇2头移动{switch(direction2){case 0:snake_2[0][1]--;break;//向上 case 1:snake_2[0][1]++;break;//向下 case 2:snake_2[0][0]--;break;//向左 case 3:snake_2[0][0]++;break;//向右 }} void direction_snake() //蛇方向(蛇头){switch(getch()){case 0xE0:switch(getch()){case 72:if(direction2 != 1) //当前不是向下走就可以向上走 direction2 = 0;break;case 80:if(direction2 != 0) //当前不是向下走就可以向上走 direction2 = 1;break;case 75:if(direction2 != 3) //当前不是向下走就可以向上走 direction2 = 2;break;case 77:if(direction2 != 2) //当前不是向下走就可以向上走 direction2 = 3;break;}break; case 'w':case 'W':if(direction != 1) //当前不是向下走就可以向上走 direction = 0;break; case 's':case 'S':if(direction != 0) //当前不是向上走就可以向下走 direction = 1;break;case 'a':case 'A':if(direction != 3) //当前不是向右走就可以向左走 direction = 2;break;case 'd':case 'D':if(direction != 2) //当前不是向左走就可以向右走 direction = 3;break;default :break;}}void check_snake() //检查蛇1状态 {void message_snake(); //打印蛇1信息int i,j;color(8); if(map[snake[0][1]][snake[0][0]] == 2) //蛇头的横坐标是行标,纵坐标是列标,吃到食物,蛇边长1格,吃到金钱后 { //立马重新产生金钱 snake_long++;score += 100;snake[snake_long-1][0] = tail[0];snake[snake_long-1][1] = tail[1];speed -= 35;if(speed<100)speed = 100;for(i = 0;i<H;i++){for(j = 0;j<L;j++){if(map[i][j] == 2)map[i][j] = 0; //原来的金钱全部消失 }}money_product();//重新产生金钱draw_snake();draw_map(); //画地图draw_snake();}message_snake(); //打印蛇1信息if(score >= target){Sleep(1500);system("cls");gotoxy(L/2,H/2);printf("蛇1率先达到目标分数,获得胜利\n");Sleep(1500);gotoxy(L/2-4,H/2+1);printf("再来一次?(Y/y) 退出(N/n) 按0返回功能菜单");shuru2:switch(getch()){case '0':game_in = 2;goto eee;break;case 'y':case 'Y':game_in = 1;goto eee;break;case 'n':case 'N':game_in = 0;goto eee;break;default:goto shuru2; }}if(map[snake[0][1]][snake[0][0]] == 1) //撞到边界或者障碍物,输了 {Sleep(1500);system("cls");gotoxy(L/2,H/2);printf("蛇1撞到障碍物,蛇2获胜\n");Sleep(1500);gotoxy(L/2-4,H/2+1);printf("再来一次?(Y/y) 退出(N/n) 按0返回功能菜单");shuru:switch(getch()){case '0':game_in = 2;break;case 'y':case 'Y':game_in = 1;break;case 'n':case 'N':game_in = 0;break;default:goto shuru; }}eee:;} void check_snake2() //检查蛇2状态 {int i,j;void message_snake2(); //打印蛇2信息color(8);if(map[snake_2[0][1]][snake_2[0][0]] == 2) //蛇头的横坐标是行标,纵坐标是列标,吃到食物,蛇边长1格,吃到金钱后 { //立马重新产生金钱 snake_long_2++;score_2 += 100;snake_2[snake_long_2-1][0] = tail_2[0];snake_2[snake_long_2-1][1] = tail_2[1];speed_2 -= 35;if(speed_2<100)speed_2 = 100;for(i = 0;i<H;i++){for(j = 0;j<L;j++){if(map[i][j] == 2)map[i][j] = 0; //原来的金钱全部消失 }}money_product();//重新产生金钱draw_snake2();draw_map(); //画地图draw_snake2(); }message_snake2(); //打印蛇2信息if(score_2 >= target){Sleep(1500);system("cls");gotoxy(L/2,H/2);printf("蛇2率先达到目标分数,获得胜利\n");Sleep(1500);gotoxy(L/2-4,H/2+1);printf("再来一次?(Y/y) 退出(N/n) 按0返回功能菜单");shuru:switch(getch()){case '0':game_in = 2;goto eee;break;case 'y':case 'Y':game_in = 1;goto eee;break;case 'n':case 'N':game_in = 0;goto eee;break;default:goto shuru; }}if(map[snake_2[0][1]][snake_2[0][0]] == 1) //撞到边界或者障碍物,输了 {Sleep(1500);system("cls");gotoxy(L/2,H/2);printf("蛇2撞到障碍物,蛇1获胜\n");Sleep(1500);gotoxy(L/2-4,H/2+1);printf("再来一次?(Y/y) 退出(N/n) 按0返回功能菜单");shuru2:switch(getch()){case '0':game_in = 2;break;case 'y':case 'Y':game_in = 1;break;case 'n':case 'N':game_in = 0;break;default:goto shuru2; }}eee:;}int menu() //功能菜单{CONSOLE_CURSOR_INFO cursor_info = {1, 0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); //隐藏关标int i,m,c = 0;if(time_game == 2)goto moshi2;else if(time_game == 3)goto moshi3;else if(time_game == 4)goto kaishi;color(12); gotoxy(36,2);printf("小小贪吃蛇");gotoxy(6,5);color(8);printf("1.闯关模式");gotoxy(26,5);printf("2.单人游戏");gotoxy(46,5);printf("3.双人游戏");gotoxy(66,5);printf("4.结束游戏");gotoxy(1,13);printf(" Loading......\n");do{for(i = 10,m = 1;i<60;i++,m+=2){color(8);gotoxy(75,13);printf(" ");gotoxy(75,13);printf("%-2d%%",m);gotoxy(75,13);printf(" ");gotoxy(75,13);printf("%-2d%%",m+1);gotoxy(i+5,14);color(3);printf("》");Sleep(i+m);c++;if(c == 50)goto end;}gotoxy(1,14);for(i = 0;i<79;i++){printf(" ");}}while(1);end:kaishi:;color(12); gotoxy(36,2);printf("小小贪吃蛇");gotoxy(6,5);color(8);printf("1.闯关模式");gotoxy(26,5);printf("2.单人游戏");gotoxy(46,5);printf("3.双人游戏");gotoxy(66,5);printf("4.结束游戏");color(3);gotoxy(1,14);for(i = 0;i<79;i++){printf(" ");}gotoxy(1,13);printf(" ");gotoxy(34,7);printf("请按相应序号进行选择");switch(getch()){case '1':system("cls");break; //闯关 case '2':moshi2:;system("cls");gotoxy(36,7);printf("游戏说明");gotoxy(32,8);printf("单人模式,设定一个目标分,达到即可胜利");gotoxy(32,9);printf("每吃到一个金币,分数增加100分");gotoxy(32,10);printf("撞到边界或障碍物,游戏失败");gotoxy(32,11);printf("请输入目标分数:");color(8);fflush(stdin);scanf("%d",&target);return 2; case '3':moshi3:;system("cls");gotoxy(36,7);printf("游戏说明");gotoxy(32,8);printf("双人对战,率先达到目标分数的一方获得胜利");gotoxy(32,9);printf("每吃到一个金币,分数增加100分");gotoxy(32,10);printf("撞到边界或障碍物,对方获胜");gotoxy(32,11);printf("请输入目标分数:");color(8);fflush(stdin);scanf("%d",&target);return 3; case '4':return 4;default :break; } }void message_snake() //打印蛇1信息{gotoxy(5,H+1);color(11); printf("玩家1--蛇1");gotoxy(5,H+2);printf("得分:%d",score);gotoxy(5,H+3);printf("上 下 左 右");gotoxy(5,H+4);printf("W/w S/s A/a D/d");gotoxy(27,H+1);printf("目标分数:%d",target);}void message_snake2() //打印蛇2信息{gotoxy(50,H+1);color(11); printf("玩家2--蛇2");gotoxy(50,H+2);printf("得分:%d",score_2);gotoxy(50,H+3);printf("上 下 左 右");gotoxy(50,H+4);printf(" ↑ ↓ ← →");} int main(){CONSOLE_CURSOR_INFO cursor_info = {1, 0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); //隐藏关标int i;menu1:system("cls");i = menu();//功能菜单if(i == 3)goto play3;else if(i == 2)goto play2;else if(i == 4)goto over_game; play3: game_in = 3;product_map(); //地图产生money_product();//产生金钱 draw_map(); //画地图draw_snake(); //画蛇1draw_snake2();message_snake(); //打印蛇1信息message_snake2(); //打印蛇2信息color(8);gotoxy(L/2-10,H/2);system("pause");gotoxy(L/2-10,H/2);printf(" "); do //双人贪吃蛇 {CONSOLE_CURSOR_INFO cursor_info = {1, 0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); //隐藏关标move_snake(); //蛇1身移动move_snake_head(); //蛇1头移动check_snake();//检查蛇1状态move_snake2(); //蛇2身移动move_snake_head2(); //蛇2头移动check_snake2();//检查蛇2状态draw_snake();draw_snake2();if(game_in == 0) // game_in0 结束游戏,1这个模式重开,2返回功能菜单 goto over_game;else if(game_in == 1){time_game = 3;goto menu1;}else if(game_in == 2){time_game = 4;goto menu1;}draw_snake();draw_snake2();Sleep(speed<speed_2?speed:speed_2); //速度最快 if(kbhit() != 0) //用kbhit函数来判断是否有按键 {direction_snake(); //移动蛇 }}while(1);//单人贪吃蛇 play2:game_in = 3;product_map(); //地图产生money_product();//产生金钱 draw_map(); //画地图draw_snake(); //画蛇1message_snake(); //打印蛇1信息color(8); gotoxy(L/2-10,H/2);system("pause");gotoxy(L/2-10,H/2);printf(" "); do //单人人贪吃蛇 {CONSOLE_CURSOR_INFO cursor_info = {1, 0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); //隐藏关标move_snake();//蛇1身移动move_snake_head(); //蛇1头移动check_snake();//检查蛇1状态if(game_in == 0)goto over_game;else if(game_in == 1){time_game = 2;goto menu1;}else if(game_in == 2){time_game = 4;goto menu1;}draw_snake();Sleep(speed-50); //速度加快 if(kbhit() != 0) //用kbhit函数来判断是否有按键 {direction_snake(); //移动蛇 }}while(1); over_game:;}

如果觉得《C语言双人贪吃蛇》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。