其实我写的博客,主要还是给自己看的吧,让自己随时随地可以查阅。不都说,这篇是贪吃蛇的。希望能给看到的萌新小伙伴一点启发吧,也欢迎大佬指点。
贪吃蛇主要有以下几个问题:
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
#include
#include
#include
#include
#include
#include
#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分数
//蛇2
int 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; //蛇速度初始300
score = 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;i0;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= 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= 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(); //画蛇1
draw_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
你可能感兴趣的:(C语言双人贪吃蛇)