大一写的C语言版贪吃蛇,今天整理的时候翻出来了,发出来纪念一下吧。。。。之前写出来的时候还挺欢喜的。。。
PS:思路也是仿照的别人的,然后自己写的代码,因为图形库处理函数的原因,只能在codeblocks装上EGE运行(C的图形库也是挺麻烦的)。
界面很low,想看的随便看看就好。
#include <stdio.h>
#include <stdlib.h>
#include<graphics.h>
#include <time.h>//随机函数头文件
#include<windows.h>
#include<conio.h>
#define N 4//开始蛇节点个数
#define S 260
typedef struct node
{
int x;
int y;
struct node *next;
} snake; //关于蛇身的结构体
int food[5]= {200,200}; //食物坐标food[0],food[1]
int re_food[5];
int live=1;//代表蛇的生死
int score=0;
int speed=210;
int s_dir=3;//初始移动方向
//1,2,3,4分别代表蛇的左,上,右,下四个移动方向
int index;
int temp=0;
int flag=0;
//创建一条蛇(链表)
snake *Creat_node()
{
int num=N;
int n=S;
snake *head=NULL,*tail=NULL,*p;
while(num--)
{
p=(snake *)malloc(sizeof(snake));
p->x=n;
n-=20;
p->y=S;
p->next=NULL;
if(head==NULL)
head=p;
else
tail->next=p;
tail=p;
}
return head;
}
//随机出现食物
void appear_food(snake *head)
{
snake *p=head;
loop:
randomize();//设定随机数种子
food[0]=random(1100);
food[1]=random(600);
while(food[0]%20!=0)//食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到
food[0]++;
while(food[1]%20!=0)
food[1]++;
//检验是否与蛇所在位置一致
while(p!=NULL)
{
if(p->x==food[0]&&p->y==food[1])
goto loop;
p=p->next;
}
}
//从键盘获取输入,即蛇的移动方向
void get_input()
{
char key;
if(kbhit())
{
key=getch();//接收对应的ASCII码
switch(key)
{
case 37://左
if(s_dir!=3)
s_dir=1;
break;
case 38://上
if(s_dir!=4)
s_dir=2;
break;
case 39://右
if(s_dir!=1)
s_dir=3;
break;
case 40://下
if(s_dir!=2)
s_dir=4;
break;
case 27://Esc(退出)
s_dir=27;
break;
case 32://空格(暂停)
s_dir=32;
break;
default:
break;
}
}
}
//蛇的移动
snake *_move(snake *head)
{
snake *str,*ptr,*ptr2;
int m,n;
m=head->x;
n=head->y;
switch(s_dir)
{
case 1:
m-=20;
break;
case 2:
n-=20;
break;
case 3:
m+=20;
break;
case 4:
n+=20;
break;
default:
break;
}
str=(snake *)malloc(sizeof(snake));
str->x=m;
str->y=n;
str->next=head;
head=str;
ptr=head->next->next;
while(ptr!=NULL)
{
if(ptr->x==str->x&&ptr->y==str->y)
{
live=0;
return str;
}
ptr=ptr->next;
}
if(str->x<=-1||str->x>=1190||str->y<=-1||str->y>=690)
{
live=0;
return str;
}
if(str->x==food[0]&&str->y==food[1])
{
score+=2;
if(score>28&&speed<300)
speed+=5;
setfillcolor(BLACK);
bar(food[0],food[1],food[0]+20,food[1]+20);
appear_food(str);
}
else
{
ptr=ptr2=str;
while(ptr->next!=NULL)
{
ptr2=ptr;
ptr=ptr->next;
}
ptr2->next=NULL;
setfillcolor(BLACK);
bar(ptr->x,ptr->y,(ptr->x)+20,(ptr->y)+20);
free(ptr);
}
return head;
}
//画图形界面
void draw_interface(snake *head)
{
snake *p=head;
xyprintf(20,20,"score:%d speed:%d",score,speed);
setfillcolor(YELLOW);
bar(food[0],food[1],food[0]+20,food[1]+20);
while(p!=NULL)
{
if(p==head)
{
setfillcolor(LIGHTGREEN);
bar(p->x,p->y,(p->x)+20,(p->y)+20);
setfillcolor(BLACK);
circle((p->x)+10,(p->y)+10,3);
}
else
{
setfillcolor(GREEN);
bar(p->x,p->y,(p->x)+20,(p->y)+20);
}
p=p->next;
}
}
void reward_food(snake *head)
{
snake *p=head;
loop:
randomize();//设定随机数种子
re_food[0]=random(1100);
re_food[1]=random(600);
while(re_food[0]%20!=0)//食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到
re_food[0]++;
while(re_food[1]%20!=0)
re_food[1]++;
//检验是否与蛇所在位置一致
while(p!=NULL)
{
if(p->x==re_food[0]&&p->y==re_food[1])
goto loop;
p=p->next;
}
if(re_food[0]==food[0]&&re_food[1]==food[1])
goto loop;
setfillcolor(RED);
bar(re_food[0],re_food[1],re_food[0]+20,re_food[1]+20);
}
int main()
{
FILE *fp;
int max_score=0;
fp=fopen("record","r");
fscanf(fp,"%d",&max_score);
fclose(fp);
snake *head=NULL,*p=head,*ptr=head;
char n;
int dir;
initgraph(1200,700);
setbkcolor(BLACK);
setfont(100,0,"宋体");
setcolor(RED);
setfontbkcolor(BLACK);
outtextxy(350,200,"贪 吃 蛇");
setfont(40,0,"宋体");
setcolor(WHITE);
setfontbkcolor(BLACK);
outtextxy(350,410,"按‘Enter’开始");
outtextxy(350,490,"按‘空格’暂停 ‘Esc’退出");
outtextxy(350,570,"方向键控制移动方向---");
loop:
n=getch();
if(n==13)
{
cleardevice();
head=Creat_node();
while(1)
{
dir=s_dir;
while(!kbhit())
{
Sleep(300-speed);
head=_move(head);
if(live==0)
break;
draw_interface(head);
}
get_input();
if(s_dir==27)
break;
if(s_dir==32)
{
lap:
n=getch();
if(n==32)
s_dir=dir;
else if(n==27)
break;
else
goto lap;
}
head=_move(head);
if(live==0)
break;
draw_interface(head);
randomize();
index=random(5000);
if(index%35==0&&flag==0)
{
flag=1;
reward_food(head);
}
if(flag==1)
{
if(head->x==re_food[0]&&head->y==re_food[1])
{
setfillcolor(BLACK);
bar(re_food[0],re_food[1],re_food[0]+20,re_food[1]+20);
if(head->next->next!=NULL)
{
ptr=head;
setfillcolor(BLACK);
bar(ptr->x,ptr->y,(ptr->x)+20,(ptr->y)+20);
head=head->next;
free(ptr);
}
temp=0;
flag=0;
}
else
{
temp++;
if(temp==6)
{
setfillcolor(BLACK);
bar(re_food[0],re_food[1],re_food[0]+20,re_food[1]+20);
flag=0;
temp=0;
}
}
}
Sleep(100);
}
}
else if(n==27)
{
closegraph();
return 0;
}
else
goto loop;
Sleep(500);
cleardevice();
setfont(100,0,"宋体");
setcolor(RED);
setfontbkcolor(BLACK);
outtextxy(300,250,"游 戏 结 束");
Sleep(2000);
cleardevice();
setbkcolor(YELLOW);
setfont(70,0,"宋体");
setcolor(BLACK);
xyprintf(250,300,"你 的 分 数 : %d",score);
while(head!=NULL)
{
p=head;
head=head->next;
free(p);
}
Sleep(2000);
if(score>max_score)
{
cleardevice();
setfont(70,0,"宋体");
setcolor(BLACK);
outtextxy(250,250," 恭喜!打破记录啦");
fp=fopen("record","w");
fprintf(fp,"%d",score);
fclose(fp);
}
getch();
closegraph();
return 0;
}