该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
#include
#include
#include
#include
#include
struct Body//定义蛇身结构体
{
short x,y;//蛇身的坐标
struct Body *next;//指向下一个蛇身的指针
};
struct Body *head;//蛇头指针
int length=sizeof(struct Body);//Body结构体所占字节数
int Delay=500;//每次移动之后的停顿时间
short X=0,Y=0;//判断蛇每次移动
short food_x,food_y,food=0;//食物坐标与是否有食物
short life=1;
short score=0;
char movdir='R';//蛇头方向'U'-up,'D'-down,'L'-left,'R'-right
short lockdelay=20;
void Loc(int, int);//光标定位函数
void Beginning();//开始界面
void CreatMap();//创建地图
void GameInit();//游戏初始化
void GameStart();//游戏开始
void DeadOrNo();//蛇的生命
char DeadOrNoByPos(int, int);//蛇的生命
void JudgeFood();
void MakeFood();//制造食物
void ThroWall();//蛇可穿墙
void SnakeMove();//蛇的移动和下面两个函数一起运用
void MoveNo(struct Body *p_body,struct Body *nofood);//没有食物时蛇的移动
void MoveYes(struct Body *yesfood);//有食物时蛇的移动
void DrawSnake(char);//画蛇
void Ending();//结束界面
void HiSleep(int);
int main(void)//主函数
{
srand((unsigned int)time(NULL));//随即种子
again:;
Beginning();//开始欢迎界面
GameInit();//界面初始化
GameStart();//游戏开始
Ending();//结束界面
while(1)
{
if(kbhit())
getch();
else
break;
}
if(getch()!=27)//按ESC键退出游戏(蛇死亡之后)
goto again;
Loc(25,24);
return 0;
}
void Beginning()//开始界面
{
int initx=14,inity=11,init=2;//下面printf字开始右移的初始位置,init代表左右方向
char ch1='\0';
time_t start,end;
}
void CreatMap()//创造地图
{
int i;
for(i=0;i<=56;i+=2)//上下边框
{
Loc(i,0);
printf("□");
Loc(i,24);
printf("□");
}
for(i=0;i<=24;i++)//左右边框
{
Loc(0,i);
printf("□");
Loc(56,i);
printf("□");
}
}
void GameInit()//游戏初始化,创建链表与初始化蛇身,初始化地图
{
struct Body *p_cur,*p_new;//定义四个蛇身指针
int xh;
CreatMap();
head=(struct Body *)malloc(length);
head->x=12;head->y=2;
p_cur=head;
p_cur->next=NULL;
for(xh=0;xh<3;xh++)
{
p_new=(struct Body *)malloc(length);
p_cur->next=p_new;
p_new->x=p_cur->x-2;
p_new->y=p_cur->y;
p_cur=p_new;
p_cur->next=NULL;
}
Delay=500;
food=0;
life=1;
score=0;
movdir='R';
lockdelay=20;
DrawSnake(0);
Loc(65,3);
puts("每吃一个");
Loc(64,4);
puts("蛇会加速哦");
Loc(61,13);
puts("控制键: ↑←↓→");//不会变的游戏提示
}
void GameStart()//游戏开始
{
while(1)
{
DeadOrNo();
if(life==0)//当生命为0时蛇死亡,退出游戏
break;
MakeFood();//制造食物
if(GetAsyncKeyState(VK_UP)&&movdir!='D'&&movdir!='U')//四个if判断是否有方向键输入
movdir='U';
else if(GetAsyncKeyState(VK_DOWN)&&movdir!='U'&&movdir!='D')
movdir='D';
else if(GetAsyncKeyState(VK_LEFT)&&movdir!='R'&&movdir!='L')
movdir='L';
else if(GetAsyncKeyState(VK_RIGHT)&&movdir!='L'&&movdir!='R')
movdir='R';
SnakeMove();//蛇的移动,每次移动一格
Loc(62,7);
printf("得分: %3d",score);//定位,打出所得分数
Loc(62,10);
printf("速度: %5.1f",1000.0/(float)Delay);//定位,打出即时速度,越小越快
HiSleep(Delay);//刷新一次的速度
}
}
void DeadOrNo()//判断蛇死没死
{
struct Body *p_body=head;
while(p_body->next!=NULL)//定位到最后一个蛇身
{
p_body=p_body->next;
if(p_body->x==head->x&&p_body->y==head->y)//如果有任何一个蛇身坐标与蛇头重合,蛇即死亡
life=0;
}
}
char DeadOrNoByPos(int x, int y)
{
struct Body *p_body=head;
while(p_body->next!=NULL)//定位到最后一个蛇身
{
if(p_body->x==x&&p_body->y==y)//如果有任何一个蛇身坐标与蛇头重合,蛇即死亡
return 1;
p_body=p_body->next; //假设情况,忽略蛇尾
}
return 0;
}
void JudgeFood()//判断食物是否与蛇身重叠
{
struct Body *p_body=head;//指向蛇头
while(p_body!=NULL)//当p_body指向最后一节跳出
{
if(food_x==p_body->x&&food_y==p_body->y)//如蛇身与食物重叠则在制造一个食物
{food=0;Loc(62,8);MakeFood();}
p_body=p_body->next;
}
}
void MakeFood()//制造食物
{
if(food==0)
{
food_x=rand()%53+2;
food_y=rand()%23+1;
if(food_x%2==1)
food_x++;//如果坐标为奇数,变为偶数坐标
food=1;
JudgeFood();
}
}
void ThroWall(struct Body *p)//穿墙
{
if(p->x==56)//右进左出
p->x=2;
if(p->x==0)//左进右出
p->x=54;
if(p->y==0)//上进下出
p->y=23;
if(p->y==24)//下进上出
p->y=1;
}
void SnakeMove()//蛇的移动与吃食物,其实就这段最难写
{
struct Body *p_body;//临时结构指针
struct Body *nofood;//没食物
struct Body *yesfood;//有食物
struct Body tmppos;
switch(movdir)
{
case 'U':X=0;Y=-1;break;
case 'D':X=0;Y=1;break;
case 'L':X=-2;Y=0;break;
case 'R':X=2;Y=0;break;
}
tmppos=*head;
tmppos.x+=X;
tmppos.y+=Y;
ThroWall(&tmppos);
if(DeadOrNoByPos(tmppos.x,tmppos.y))
{
if(lockdelay<=0)
life=0;
else
lockdelay--;
}
else
{
lockdelay=(1000/Delay)+1;
if(tmppos.x==food_x&&tmppos.y==food_y)//下一格有食物
MoveYes(yesfood);
else
{
nofood=(struct Body *)malloc(length);//为没食物分配空间
MoveNo(p_body,nofood);
}
}
DrawSnake(1);//画蛇
Loc(food_x,food_y);
printf("●");
}
void MoveYes(struct Body *yesfood)//有食物的移动
{
yesfood=(struct Body *)malloc(length);//每次调用都要为其分配空间,因为每次吃到了食物蛇身会长一节,必须为蛇身在分配一个空间
yesfood->x=food_x;
yesfood->y=food_y;
yesfood->next=head;//新结构拥有了蛇吃完食物的空间
head=yesfood;//在赋给头指针
food=0; score+=1; //加分
MakeFood();//制造食物
}
void MoveNo(struct Body *p_body,struct Body *nofood)//没食物的移动
{
nofood->x=head->x+X;
nofood->y=head->y+Y;
ThroWall(nofood);
nofood->next=head;
head=nofood;//同上
p_body=head;
while((p_body->next)->next!=NULL)//使p_body指向倒数第二个蛇身
p_body=p_body->next;
Loc((p_body->next)->x,(p_body->next)->y);//定位到最后一节蛇身
printf(" ");//消除蛇身
free(p_body->next);//释放空间
p_body->next=NULL;//使倒数第二节成为新的蛇尾
}
void DrawSnake(char simple)//画出蛇头到蛇尾
{
int drawcount=0;
struct Body *p_body=head;//指向蛇头
while(p_body!=NULL)//当p_body指向最后一节跳出
{
Loc(p_body->x,p_body->y);
printf(p_body==head?"■":"□");
drawcount++;
p_body=p_body->next;
if(simple&&drawcount==2)
break;
}
}
void Ending()//结束界面
{
int num=0;
char str[]={"Thank you for playing the snaKe game! "};
system("cls");
Loc(32,9);printf("Game Over!!");
while(str[num]!='\0')
{
Loc(20+num,11);
putchar(str[num]);
num++;
HiSleep(100);
}
Loc(28,13);
puts("按ESC键退出");
Loc(30,15);
puts("按任意键重来...");
}
void Loc(int x, int y)//x为列坐标,y为行坐标,这个不用说了吧~
{
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
}
void HiSleep(int ms)
{
int x;
x=clock();
while(clock()-x
//Sleep(0);
}