目录
一、定义
1.蛇的属性定义:
2.定义食物
3.定义全局变量——蛇头,食物(apple),屏幕尺寸,按键操作
二、蛇的函数编写
1.蛇初始化
2.画蛇
3.增加蛇的长度
4.蛇动
5.按键控制
6.蛇死判定(以及穿墙处理)
三、食物(apple)的函数编写
1.画食物
2.食物初始化
3.食物刷新
4.蛇吃食物增加长度
5.分数显示
四、完整代码
五、运行结果
六、小结
填坑:之前写过用数组实现贪吃蛇,现在使用单链表实现贪吃蛇小游戏。
完整代码在末尾,直接复制即可运行
typedef struct Snake{
int x;
int y;
char dir;
Snake* next;
}snake;
typedef struct Food{
int x;
int y;
int flag;
int grade;
}food;
#define screen_long 640//x
#define screen_width 480//y
#define up 87//W
#define down 83//S
#define left 65//A
#define right 68//D
snake* head;
food apple;
void Snake_Init(void )
{
snake *body1;
snake *body2;
snake *body3;
head=(snake*) malloc (sizeof (snake));
body1=(snake*) malloc(sizeof (snake));
body2=(snake*) malloc(sizeof (snake));
body3=(snake*) malloc(sizeof (snake));
head->next=body1;
body1->next=body2;
body2->next=body3;
body3->next=NULL;
body1->dir=right;
body2->dir=right;
body3->dir=right;
head->dir=up;
body1->x=screen_long/2+20;
body1->y=screen_width/2;
body2->x=screen_long/2+10;
body2->y=screen_width/2;
body3->x=screen_long/2;
body3->y=screen_width/2;
head->x=screen_long/2+30;
head->y=screen_width/2;
}
void Snake_Draw(void )
{
snake *p=head;
setlinecolor(RGB(0 ,134 ,139));
setfillcolor(RGB(0 ,250 ,0));
fillrectangle(p->x,p->y,p->x+10,p->y+10);
setlinecolor(RGB(0 ,134 ,139));
setfillcolor(RGB(0 ,200 ,0));
while(p->next!=NULL)
{
p=p->next;
fillrectangle(p->x,p->y,p->x+10,p->y+10);
}
}
snake *Snake_Create(void )
{
snake *p;
p=(snake*) malloc(sizeof (snake));
p->x=0;
p->y=0;
p->dir=0;
p->next=NULL;
return p;
}
void Snake_Move(void )
{
snake *p=head;
snake *q=head;
while (p->next!=NULL)
{
q=p;
p=p->next;
}
free(p);
q->next=NULL;
snake *new_head=Snake_Create();
switch (head->dir) {
case up:
new_head->x=head->x;
new_head->y=head->y-10;
break;
case down:
new_head->x=head->x;
new_head->y=head->y+10;
break;
case right:
new_head->x=head->x+10;
new_head->y=head->y;
break;
case left:
new_head->x=head->x-10;
new_head->y=head->y;
break;
}
new_head->dir=head->dir;
new_head->next=head;
head=new_head;
}
void Key_Control(void )
{
char KeyNum;
KeyNum=getch();
switch (head->dir)
{
case right:
if (KeyNum==up)
head->dir=up;
else
head->dir=down;
break;
case left:
if (KeyNum==up)
head->dir=up;
else
head->dir=down;
break;
case up:
if (KeyNum==right)
head->dir=right;
else
head->dir=left;
break;
case down:
if (KeyNum==right)
head->dir=right;
else
head->dir=left;
break;
}
}
void Snake_Die(void )
{
snake *p=head->next;
while(p->next!=NULL)
{
if((head->x==p->x)&&(head->y==p->y))
{
outtextxy(200,200,"eat yourself!");
MessageBox(hwnd,"Game Over!","eat yourself",MB_OK);
Snake_Init();
apple.grade=0;
} else{
p=p->next;
}
}
if(head->x>screen_long)
{
head->x=head->x-screen_long-10;
} else if (head->y>screen_width)
{
head->y=head->y-screen_width-10;
}else if (head->x<0)
{
head->x=head->x+screen_long;
}else if (head->y<0)
{
head->y=head->y+screen_width;
}
}
void Apple_Draw(void )
{
setlinecolor(RGB(250 ,0 ,0));
setfillcolor(RGB(255 ,0 ,0));
fillrectangle(apple.x,apple.y,apple.x+10,apple.y+10);
}
void Apple_Init(void)
{
apple.x=rand()%(screen_long/10)*10;
apple.y=rand()%(screen_width/10)*10;
apple.flag=1;
apple.grade=0;
Apple_Draw();
}
void Apple_Refresh(void)
{
Apple_Draw();
if(apple.flag==0)
{
apple.grade+=10;
apple.x=rand()%(screen_long/10)*10;
apple.y=rand()%(screen_width/10)*10;
apple.flag=1;
}
}
void Food_Eat(void)
{
if((head->x==apple.x)&&(head->y==apple.y))
{
snake *q=Snake_Create();
apple.flag=0;
snake *p=head;
while (p->next!=NULL)
{
p=p->next;
}
// switch (head->dir) {
// case up:
// q->x=p->x;
// q->y=p->y+10;
// break;
// case down:
// q->x=p->x;
// q->y=p->y-10;
// break;
// case right:
// q->x=p->x-10;
// q->y=p->y;
// break;
// case left:
// q->x=p->x+10;
// q->y=p->y;
// break;
// }
p->next=q;
}
}
void Grade_Show(void )
{
char grade[100]="";
sprintf(grade,"%d",apple.grade);
settextcolor(RGB(0 ,150 ,150));
outtextxy(screen_long-100,20,"Grade:");
outtextxy(screen_long-40,20,grade);
}
#include // 引用图形库头文件
#include
#include "stdio.h"
#include "time.h"
#include "stdlib.h"
#define screen_long 640//x
#define screen_width 480//y
#define up 87//W
#define down 83//S
#define left 65//A
#define right 68//D
HWND hwnd=NULL;
typedef struct Food{
int x;
int y;
int flag;
int grade;
}food;
typedef struct Snake{
int x;
int y;
char dir;
Snake* next;
}snake;
snake* head;
food apple;
void Snake_Init(void )
{
snake *body1;
snake *body2;
snake *body3;
head=(snake*) malloc (sizeof (snake));
body1=(snake*) malloc(sizeof (snake));
body2=(snake*) malloc(sizeof (snake));
body3=(snake*) malloc(sizeof (snake));
head->next=body1;
body1->next=body2;
body2->next=body3;
body3->next=NULL;
body1->dir=right;
body2->dir=right;
body3->dir=right;
head->dir=up;
body1->x=screen_long/2+20;
body1->y=screen_width/2;
body2->x=screen_long/2+10;
body2->y=screen_width/2;
body3->x=screen_long/2;
body3->y=screen_width/2;
head->x=screen_long/2+30;
head->y=screen_width/2;
}
void Snake_Draw(void )
{
snake *p=head;
setlinecolor(RGB(0 ,134 ,139));
setfillcolor(RGB(0 ,250 ,0));
fillrectangle(p->x,p->y,p->x+10,p->y+10);
setlinecolor(RGB(0 ,134 ,139));
setfillcolor(RGB(0 ,200 ,0));
while(p->next!=NULL)
{
p=p->next;
fillrectangle(p->x,p->y,p->x+10,p->y+10);
}
}
snake *Snake_Create(void )
{
snake *p;
p=(snake*) malloc(sizeof (snake));
p->x=0;
p->y=0;
p->dir=0;
p->next=NULL;
return p;
}
void Snake_Move(void )
{
snake *p=head;
snake *q=head;
while (p->next!=NULL)
{
q=p;
p=p->next;
}
free(p);
q->next=NULL;
snake *new_head=Snake_Create();
switch (head->dir) {
case up:
new_head->x=head->x;
new_head->y=head->y-10;
break;
case down:
new_head->x=head->x;
new_head->y=head->y+10;
break;
case right:
new_head->x=head->x+10;
new_head->y=head->y;
break;
case left:
new_head->x=head->x-10;
new_head->y=head->y;
break;
}
new_head->dir=head->dir;
new_head->next=head;
head=new_head;
}
void Key_Control(void )
{
char KeyNum;
KeyNum=getch();
switch (head->dir)
{
case right:
if (KeyNum==up)
head->dir=up;
else
head->dir=down;
break;
case left:
if (KeyNum==up)
head->dir=up;
else
head->dir=down;
break;
case up:
if (KeyNum==right)
head->dir=right;
else
head->dir=left;
break;
case down:
if (KeyNum==right)
head->dir=right;
else
head->dir=left;
break;
}
}
void Apple_Draw(void )
{
setlinecolor(RGB(250 ,0 ,0));
setfillcolor(RGB(255 ,0 ,0));
fillrectangle(apple.x,apple.y,apple.x+10,apple.y+10);
}
void Apple_Init(void)
{
apple.x=rand()%(screen_long/10)*10;
apple.y=rand()%(screen_width/10)*10;
apple.flag=1;
apple.grade=0;
Apple_Draw();
}
void Apple_Refresh(void)
{
Apple_Draw();
if(apple.flag==0)
{
apple.grade+=10;
apple.x=rand()%(screen_long/10)*10;
apple.y=rand()%(screen_width/10)*10;
apple.flag=1;
}
}
void Food_Eat(void)
{
if((head->x==apple.x)&&(head->y==apple.y))
{
snake *q=Snake_Create();
apple.flag=0;
snake *p=head;
while (p->next!=NULL)
{
p=p->next;
}
// switch (head->dir) {
// case up:
// q->x=p->x;
// q->y=p->y+10;
// break;
// case down:
// q->x=p->x;
// q->y=p->y-10;
// break;
// case right:
// q->x=p->x-10;
// q->y=p->y;
// break;
// case left:
// q->x=p->x+10;
// q->y=p->y;
// break;
// }
p->next=q;
}
}
void Grade_Show(void )
{
char grade[100]="";
sprintf(grade,"%d",apple.grade);
settextcolor(RGB(0 ,150 ,150));
outtextxy(screen_long-100,20,"Grade:");
outtextxy(screen_long-40,20,grade);
}
void Snake_Die(void )
{
snake *p=head->next;
while(p->next!=NULL)
{
if((head->x==p->x)&&(head->y==p->y))
{
outtextxy(200,200,"eat yourself!");
MessageBox(hwnd,"Game Over!","eat yourself",MB_OK);
Snake_Init();
} else{
p=p->next;
}
}
if(head->x>screen_long)
{
head->x=head->x-screen_long-10;
} else if (head->y>screen_width)
{
head->y=head->y-screen_width-10;
}else if (head->x<0)
{
head->x=head->x+screen_long;
}else if (head->y<0)
{
head->y=head->y+screen_width;
}
}
int main(void )
{
hwnd = initgraph(screen_long, screen_width);
srand((unsigned int) time(NULL));
setbkcolor(WHITE);
cleardevice();
Snake_Init();
Apple_Init();
while(1)
{
while (kbhit())
{
Key_Control();
}
Snake_Die();
Grade_Show();
Food_Eat();
Apple_Refresh();
Snake_Draw();
Snake_Move();
Sleep(100);
cleardevice();
}
getch();
}
链表比直接使用数组进行开发难度高一点,但顺便复习了数据结构的知识,尤其是在蛇运动的时候,将最后一个节点删除,并新加一个节点在蛇头,并把新加的节点变成蛇头的操作是最困难的。这也是本次小项目所学习到的点。
源码自取:
链接:https://pan.baidu.com/s/1N5PeeNeQ68MbHPYZqyoSEQ
提取码:3947