C语言实现链表贪吃蛇
用C语言链表写的贪吃蛇(程序设计时做的,做的不好大佬勿喷)
借助游戏内容分析贪吃蛇所需的功能主要包括这几块:
1.移动光标模块
2.打印地图模块和基本规则信息
读取最高分文件
3.打印初始蛇模块
打印时给予蛇的初始移动方向
4.产生食物模块
1)、保证食物在地图内产生
2)、保证食物不能出现在蛇体
5.蛇的生命状态判断模块
1)、撞墙导致死亡
2)、头撞身体部位死亡
6.运行模块
1)、让蛇移动
2)、根据按键来改变蛇的移动方向
3)、对待分数的增加游戏难度的增加
4)、蛇在吃食物后分数的增加
7.结束模块
在遇到撞墙或者撞自己部位死亡时结束程序,并进行分数与历史最高分作比较,最终达到最高分的更新
以下为代码
#include <stdlib.h> #include <stdio.h> #include <conio.h>//控制台输入和输出 #include <windows.h>//窗口函数 #include <time.h> #define W 1//蛇的运动方向W:上 S:下 A: 左 D:右 #define S 2 #define A 3 #define D 4 /* 定义全局变量 */ typedef struct{ int x; int y; }place;//定义坐标结构体 typedef struct ZB{ place data; struct ZB *next; }snake;//定义蛇的链表 /* 定义全局链表 */ snake *head,*p,*q,*h;// place food;//定义食物坐标 int score=0,bestscore,game_flag=0,ch,sleep=400;//定义得分score死亡判断game_flag方向判断ch蛇的速度sleep /* 函数声明 */ void gotoxy(int x,int y);//定位光标 void map_creat();//运用定位函数打印地图 void ini_snack();//随机产生蛇 void cre_food();//随机产生食物 void live_jud_1();//判断自己是否撞墙死亡 void live_jud_2();//判断自己是否撞到自己 void move();//蛇的移动 void rungame();//游戏运行 void gameover();//游戏结束界面 void changch();//改变方向 int color(int c);//改颜色函数 /* 构建定位函数 */ int color(int c) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c); //更改文字颜色 return 0; } void gotoxy(int x,int y)//定位光标 { COORD pos; HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); pos.X=x; pos.Y=y; SetConsoleCursorPosition(handle,pos); } /* 打印地图 */ void map_creat()//运用定位函数打印地图 { FILE *fp;//创建一个记录最高分的文件 fp=fopen("score.1","r"); fscanf(fp,"%d",&bestscore);//读取最高分 fclose(fp); gotoxy(54,26); printf("Your Best Score : %d\t", bestscore);//打印出最高分 int i,j; for(i=0;i<48;i++) { gotoxy(i,0); printf("#"); color(6); gotoxy(i,26); printf("#"); color(6); } for(j=0;j<26;j++) { gotoxy(0,j); printf("#"); color(6); gotoxy(48,j); printf("#"); color(6); } gotoxy(54,10); printf("游戏规则:"); gotoxy(54,12); printf("向上移动:↑\n"); gotoxy(54,14); printf("向下移动:↓\n"); gotoxy(54,16); printf("向左移动:←\n"); gotoxy(54,18); printf("向右移动:→\n"); gotoxy(54,20); printf("吃一个食物分数加10"); gotoxy(54,22); printf("按空格键暂停游戏"); gotoxy(54,24); printf("按ESC直接结束游戏"); } /* 构建初始蛇 */ void ini_snack()//产生蛇 { int i; /* 采用尾插法构建蛇的链表初始长度设为二 */ head=(snake *)malloc(sizeof(snake)); head->data.x=48/2; head->data.y=26/2; head->next=NULL; h=head; for(i=1;i<=2;i++) { p=(snake *)malloc(sizeof(snake)); p->data.x=48/2+i; p->data.y=26/2; h->next=p; h=p; } p->next=NULL; /* 将蛇打印出来 */ h=head; while(h!=NULL) { gotoxy(h->data.x,h->data.y); color(5); printf("@"); h=h->next; } ch=W;//蛇的初始方向 } /* 随机产生食物 */ void cre_food()//随机产生食物 { srand((unsigned)time(NULL));//为了防止每次产生的随机数相同,种子设置为time /* 随机产生食物 */ food.x=rand()%(48-2)+1; food.y=rand()%(26-2)+1; while(p!=NULL) { /* 判断食物是否与蛇重合,如果重合重新产生 */ if(p->data.x==food.x&&p->data.y==food.y) cre_food(); p=p->next; } gotoxy(food.x,food.y); color(1); printf("$");//打印食物 } /* 判断是否死亡 */ void live_jud_1()//判断自己是否撞墙死亡 { if(head->data.x==0||head->data.x==48||head->data.y==0||head->data.y==26)//撞墙 { game_flag=1; gameover(); } } void live_jud_2()//判断自己是否撞到自己 { q=head->next; while(q!=NULL) { if(head->data.x==q->data.x&&head->data.y==q->data.y)//撞自己 { { game_flag=2; gameover(); } break; } q=q->next; } } /* 游戏进行界面 */ void move() { snake *l; live_jud_1(); l=(snake *)malloc(sizeof(snake)); /* 构建一个新的节点通,过新节点来表示下一次头节点所在的位置 将新节点当作移动后的头节点 如果新头节点的坐标等于食物的坐标得分加10,食物的标志变为1 因为蛇的链表长度加了一,如果是移动的话找出尾节点并打印出 然后删掉该尾节点 如果吃到了食物就直接将蛇打印出来 */ if(ch==W) { l->data.x=head->data.x; l->data.y=head->data.y-1; if(l->data.x==food.x&&l->data.y==food.y) { l->next=head; head=l; q=head; while(q!=NULL)//将蛇重新打印一边 { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } score+=10; cre_food();//构建新的食物 } else { l->next=head; head=l; q=head; while(q->next->next!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } gotoxy(q->next->data.x,q->next->data.y); printf(" ");//将蛇尾去掉 free(q->next); q->next=NULL; } } if(ch==A) { l->data.x=head->data.x-1; l->data.y=head->data.y; if(l->data.x==food.x&&l->data.y==food.y) { l->next=head; head=l; q=head; while(q!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } score+=10; cre_food(); } else { l->next=head; head=l; q=head; while(q->next->next!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } gotoxy(q->next->data.x,q->next->data.y); printf(" "); free(q->next); q->next=NULL; } } if(ch==S) { l->data.x=head->data.x; l->data.y=head->data.y+1; if(l->data.x==food.x&&l->data.y==food.y) { l->next=head; head=l; q=head; while(q!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } score+=10; cre_food(); } else { l->next=head; head=l; q=head; while(q->next->next!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } gotoxy(q->next->data.x,q->next->data.y); printf(" "); free(q->next); q->next=NULL; } } if(ch==D) { l->data.x=head->data.x+1; l->data.y=head->data.y; if(l->data.x==food.x&&l->data.y==food.y) { l->next=head; head=l; q=head; while(q!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } score+=10; cre_food(); } else { l->next=head; head=l; q=head; while(q->next->next!=NULL) { gotoxy(q->data.x,q->data.y); color(5); printf("@"); q=q->next; } gotoxy(q->next->data.x,q->next->data.y); printf(" "); free(q->next); q->next=NULL; } } live_jud_2();//判断是否撞自己死亡 } void rungame()//运行游戏 { while(1) { gotoxy(54,8); printf("Your Score:%d",score); /* 以下确保不能向上运动时改方向为向下等情况 */ if(GetAsyncKeyState(VK_UP)&&ch!=S) ch=W; else if(GetAsyncKeyState(VK_DOWN)&&ch!=W) ch=S; else if(GetAsyncKeyState(VK_LEFT)&&ch!=D) ch=A; else if(GetAsyncKeyState(VK_RIGHT)&&ch!=A) ch=D; /* 根据分数和Sleep函数来确定游戏难度 */ if(score>=50&&score<100) sleep=300; else if(score>=100&&score<300) sleep=250; else if(score>=300) sleep=200; if(GetAsyncKeyState(VK_SPACE))//输入space暂停游戏 { while(1) { Sleep(300); if(GetAsyncKeyState(VK_SPACE)) break; } } else if (GetAsyncKeyState(VK_ESCAPE))//输入ESC直接结束游戏 { game_flag=3; gameover(); } Sleep(sleep); move(); } } /* 游戏结束界面 */ void gameover()//游戏结束界面 { FILE *fp; system("cls");//清屏 gotoxy(48/2,26/2-2); printf("\tGame Over!!!");//打印出游戏结束界面 gotoxy(48/2,26/2); if(game_flag==1) printf("\t你撞墙了!!!\n"); else if(game_flag==2) printf("\t傻孩子!你不能吃你自己!!!\n"); else if(game_flag==3) printf("\t您已结束游戏!"); gotoxy(48/2,26/2+2); printf("\tYour score:%d\n",score);//打印出得到的分数 if(score>bestscore)//如果此次游戏分数大于以前最高分 { fp=fopen("score.1","w"); fprintf(fp,"%d",score);//将此次分数保存在最高分文件里 fclose(fp); } system("pause"); exit(0); } /* 主函数 */ int main() { system("color 9"); map_creat(); ini_snack(); cre_food(); rungame(); return 0; }
更多有趣的经典小游戏实现专题,分享给大家:
C++经典小游戏汇总
python经典小游戏汇总
python俄罗斯方块游戏集合
JavaScript经典游戏 玩不停
javascript经典小游戏汇总
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)