闲话不多说,直接上代码
#include "stdio.h"
#include "windows.h"
#include "stdbool.h"
/*坐标系
-------------> y
|
|
|
|
|x
*/
/*
按键:移动: 8
4 5 6
9:暂停
*/
#define X 20
#define Y 70
#define WAIT_TIME 700//移动一次需要的时间
enum
{
UP,
DOWN,
LEFT,
RIGHT
};
//对食物进行标记
enum
{
food1=2,
food2
};
int Map[X][Y];
int score=0;
typedef struct
{
int x;
int y;
}POSE;
typedef struct
{
POSE pose[X*Y];//蛇最大长度应为(x-2)(y-2),这里为了省事
int len;
int direction;
bool eatfood;
}SHAKE;
SHAKE Shake;
//制作步骤差不多如下
void Init(); //2
void map(); //1
void goxy(); //3
void ShakeGrape(); //4
void move(); //5
void key(); //6
void foods(); //7
int FoodCheck(int x,int y); //8
int isgameover(); //9
void show(); //10
void read(); //11
int main(void)
{
read();
Init();
map();
foods();
while(1)
{
ShakeGrape();
show();
Sleep(WAIT_TIME);
key();
move();
if(isgameover())
{
system("cls"); //清除屏幕内容
printf("Game Over\n");
printf("最后得分:%d\n",score);
system("pause");
break;
}
if(Map[Shake.pose[0].x][Shake.pose[0].y]==food1)
{
Map[Shake.pose[0].x][Shake.pose[0].y]=0;
Shake.eatfood =true;
foods();
score+=1;
}
else if(Map[Shake.pose[0].x][Shake.pose[0].y]==food2)
{
Map[Shake.pose[0].x][Shake.pose[0].y]=0;
Shake.eatfood =true;
foods();
score+=10;
}
}
return 0;
}
void Init() //初始化
{
int i;
srand((unsigned)time(NULL));
//srand设置随机种子,相同的随机种子对应的rand产生的随机数是相同的
//设置随机种子,和时间有关,避免每次都一样,由于不需要种子的数据,直接用空指针NULL获取数据
goxy(0,0);
CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //清除光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
Shake.len =4;
Shake.pose[0].x =X/2;
Shake.pose[0].y =Y/2;
for(i=0;i<Shake.len;i++)
{
Shake.pose[i].x =Shake.pose[0].x-i ;
Shake.pose[i].y =Shake.pose[0].y;
}
Shake.direction =DOWN;
}
void map()
{
int x,y;
for(x=0;x<X;x++)
{ //围墙
Map[x][0]=1;
Map[x][Y-1]=1;
}
for(y=0;y<Y;y++)
{
Map[0][y]=1;
Map[X-1][y]=1;
}
/*========================*/
for(x=0;x<X;x++)//给围墙填充图形
{
for(y=0;y<Y;y++)
{
if(Map[x][y]==1)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
void goxy(int x,int y)//移动光标到指定位置
{
COORD position={y,x};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
}
void ShakeGrape() //蛇的身体
{
int i;
for(i=0;i<Shake.len ;i++)
{
goxy(Shake.pose[i].x ,Shake.pose[i].y );
printf("0");
}
}
void move()
{
int i=0;
goxy(Shake.pose[Shake.len -1].x ,Shake.pose[Shake.len -1].y);
printf(" ");
for(i=1;i<Shake.len ;i++)
{
Shake.pose[Shake.len -i].x =Shake.pose[Shake.len -i-1].x ;
Shake.pose[Shake.len -i].y =Shake.pose[Shake.len -i-1].y ;
}
switch(Shake.direction )
{
case UP:
Shake.pose[0].x --;
break;
case DOWN:
Shake.pose[0].x ++;
break;
case LEFT:
Shake.pose[0].y --;
break;
case RIGHT:
Shake.pose[0].y ++;
break;
}
if(Shake.eatfood )
{
Shake.len ++;
Shake.eatfood =false;
}
}
void key()
{
if(kbhit()!=0)//有按键输入值不为0,没有为0
{
char keys;
while(kbhit()!=0)
{
keys=getch();//获取键值
}
switch(keys)
{
case '8':
if(Shake.direction !=DOWN) //防止缩头
Shake.direction=UP;
break;
case '5':
if(Shake.direction!=UP)
Shake.direction=DOWN;
break;
case '4':
if(Shake.direction!=RIGHT)
Shake.direction=LEFT;
break;
case '6':
if(Shake.direction!=LEFT)
Shake.direction=RIGHT;
break;
case '9':
goxy(X+2,0);
system("pause");
break;
}
}
}
void foods()
{
int x,y;
int k;
do
{
x=rand()%X;
y=rand()%Y;
}while(!FoodCheck(x,y));
k=rand()%5;
goxy(x,y);
if(k==4)//随机食物
{
Map[x][y]=food1;
printf("$");
}
else
{
Map[x][y]=food2;
printf("+");
}
}
int FoodCheck(int x,int y)//检查食物位置是否合规
{
int i=0;
if(x==0 || x==(X-1) || y==0 || y==(Y-1))//放墙上
{
return 0;
}
for(i=0;i<Shake.len ;i++)
{
if(Shake.pose[i].x ==x && Shake.pose[i].y==y )//放蛇身上
{
return 0;
}
}
return 1;
}
int isgameover()
{
int i=0;
if(Shake.pose[0].x==0 || Shake.pose[0].x==(X-1) || Shake.pose[0].y ==(Y-1) || Shake.pose[0].y==0)//撞墙
{
return 1;
}
for(i=2;i<Shake.len ;i++)//咬到蛇身
{
if(Shake.pose[0].x ==Shake.pose[i].x && Shake.pose[0].y ==Shake.pose[i].y)
{
return 1;
}
}
return 0;
}
void show()
{
goxy(X,0);
printf("得分:%d",score);
}
void read()
{
printf(" 控制键:4 5 6 8\n");
printf(" 暂停键:9\n");
printf(" +:10分\n");
printf(" $:1分\n");
printf(" 制作时间:2021-3-21\n");
printf(" 按enter键即可开始\n");
printf(" \n");
system("pause");
system("cls");
}