C语言实现贪吃蛇小游戏开发

本文实例为大家分享了C语言实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下

程序介绍

代码

#include<stdafx.h>            //vc自带头文件 #include<stdio.h>            //标准输入输出函数库 #include<time.h>            //用于获得随机数 #include<windows.h>            //控制dos界面 #include<stdlib.h>            //即standard library标志库头文件,里面定义了一些宏和通用工具函数 #include<conio.h>            //接收键盘输入输出 /*******宏  定  义*******/ #define U 1 #define D 2 #define L 3  #define R 4      //蛇的状态,U:上 ;D:下;L:左 R:右 /*******定  义  全  局  变  量 *******/ typedef struct snake         //蛇身的一个节点 {     int x;     int y;     struct snake *next; }snake; int score=0,add=10;            //总得分与每次吃食物得分 int HighScore = 0;            //最高分 int status,sleeptime=200;    //蛇前进状态,每次运行的时间间隔 snake *head, *food;            //蛇头指针,食物指针 snake *q;                    //遍历蛇的时候用到的指针 int endgamestatus=0;        //游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏。 HANDLE hOut;                //控制台句柄 /*******函  数  声  明 *******/ void gotoxy(int x,int y);   //设置光标位置 int color(int c);           //更改文字颜色 void printsnake();          //字符画---蛇 void welcometogame();       //开始界面 void createMap();           //绘制地图 void scoreandtips();        //游戏界面右侧的得分和小提示 void initsnake();           //初始化蛇身,画蛇身 void createfood();          //创建并随机出现食物 int biteself();             //判断是否咬到了自己 void cantcrosswall();       //设置蛇撞墙的情况 void speedup();                //加速 void speeddown();            //减速 void snakemove();           //控制蛇前进方向 void keyboardControl();     //控制键盘按键 void Lostdraw();            //游戏结束界面 void endgame();             //游戏结束 void choose();                //游戏失败之后的选择 void File_out();            //在文件中读取最高分 void File_in();                //储存最高分进文件 void explation();           //游戏说明 /**  * 设置光标位置  */ void gotoxy(int x,int y) {     COORD c;     c.X=x;     c.Y=y;     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c); } /**  * 文字颜色函数      此函数的局限性:1、只能Windows系统下使用   2、不能改变背景颜色  */ int color(int c) {     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);        //更改文字颜色     return 0; } /* *   字符画---蛇 */ void printsnake() {     gotoxy(35,1);     color(6);     printf("/^\\/^\\");      //蛇眼睛     gotoxy(34,2);     printf("|__|  O|");      //蛇眼睛     gotoxy(33,2);     color(2);     printf("_");     gotoxy(25,3);     color(12);     printf("\\/");          //蛇信     gotoxy(31,3);     color(2);     printf("/");     gotoxy(37,3);     color(6);     printf(" \\_/");         //蛇眼睛     gotoxy(41,3);     color(10);     printf(" \\");     gotoxy(26,4);     color(12);     printf("\\____");       //舌头     gotoxy(32,4);     printf("_________/");     gotoxy(31,4);     color(2);     printf("|");     gotoxy(43,4);     color(10);     printf("\\");     gotoxy(32,5);     color(2);     printf("\\_______");    //蛇嘴     gotoxy(44,5);     color(10);     printf("\\");     gotoxy(39,6);     printf("|     |                  \\");  //下面都是画蛇身     gotoxy(38,7);     printf("/      /                   \\");     gotoxy(37,8);     printf("/      /                    \\ \\");     gotoxy(35,9);     printf("/      /                       \\ \\");     gotoxy(34,10);     printf("/     /                          \\  \\");     gotoxy(33,11);     printf("/     /             _----_         \\   \\");     gotoxy(32,12);     printf("/     /           _-~      ~-_         |  |");     gotoxy(31,13);     printf("(      (        _-~    _--_    ~-_     _/  |");     gotoxy(32,14);     printf("\\     ~-____-~    _-~    ~-_    ~-_-~    /");     gotoxy(33,15);     printf("~-_           _-~          ~-_       _-~");     gotoxy(35,16);     printf("~--______-~                ~-___-~"); } /**  * 开始界面  */ void welcometogame() {     int n;     int i,j = 1;     gotoxy(43,18);     color(11);     printf("贪 吃 蛇 大 作 战");     color(14);                      //黄色边框     for (i = 20; i <= 26; i++)       //输出上下边框┅     {         for (j = 27; j <= 74; j++)  //输出左右边框┇         {             gotoxy(j, i);             if (i == 20 || i == 26)             {                 printf("-");             }             else if (j == 27 || j == 74)             {                 printf("|");             }         }     }     color(12);     gotoxy(35, 22);     printf("1.开始游戏");     gotoxy(55, 22);     printf("2.游戏说明");     gotoxy(35, 24);     printf("3.退出游戏");     gotoxy(29,27);     color(3);     printf("请选择[1 2 3]:[ ]\b\b");        //\b为退格,使得光标处于[]中间     color(14);     scanf("%d", &n);            //输入选项     switch (n)     {         case 1:             system("cls");             createMap();        //创建地图             initsnake();        //初始化蛇身             createfood();       //创建食物             keyboardControl();    //按键控制             break;         case 2:             explation();          //游戏说明函数             break;         case 3:             exit(0);             //退出游戏             break;         default:                //输入非1~3之间的选项             color(12);             gotoxy(40,28);             printf("请输入1~3之间的数!");             getch();            //输入任意键             system("cls");        //清屏             printsnake();             welcometogame();     } } /**  * 创建地图  */ void createMap() {     int i,j;     for(i=0;i<58;i+=2)        //打印上下边框     {         gotoxy(i,0);         color(5);            //深紫色的边框         printf("□");         gotoxy(i,26);         printf("□");     }     for(i=1;i<26;i++)        //打印左右边框     {         gotoxy(0,i);         printf("□");                                 gotoxy(56,i);         printf("□");             }     for(i = 2;i<56;i+=2)    //打印中间网格     {         for(j = 1;j<26;j++)         {             gotoxy(i,j);             color(3);             printf("■");         }     } }  /**  *  游戏界面右侧的得分和小提示  */ void scoreandtips() {     File_out();     gotoxy(64,4);     color(11);     printf("☆最高记录☆:%d",HighScore);     gotoxy(64,8);     color(14);     printf("得分:%d  ",score);     color(13);     gotoxy(73,11);     printf("小 提 示");     gotoxy(60,13);     color(6);     printf("╬ ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ ╬");     gotoxy(60,25);     printf("╬ ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅ ╬");     color(3);     gotoxy(64,14);     printf("每个食物得分:%d分",add);     gotoxy(64,16);     printf("不能撞墙,不能咬到自己");     gotoxy(64,18);     printf("用↑ ↓ ← →分别控制蛇的移动");     gotoxy(64,20);     printf("F1键加速,F2键减速");     gotoxy(64,22);     printf("空格键暂停游戏");     gotoxy(64,24);     printf("Esc键退出游戏"); }  /**  * 初始化蛇身,画蛇身  */ void initsnake() {     snake *tail;     int i;     tail=(snake*)malloc(sizeof(snake));//从蛇尾开始,头插法,以x,y设定开始的位置//     tail->x=24;             //蛇的初始位置(24,5)     tail->y=5;     tail->next=NULL;     for(i=1;i<=4;i++)       //设置蛇身,长度为5     {         head=(snake*)malloc(sizeof(snake)); //初始化蛇头         head->next=tail;        //蛇头的下一位为蛇尾         head->x=24+2*i;         //设置蛇头位置         head->y=5;         tail=head;              //蛇头变成蛇尾,然后重复循环     }     while(tail!=NULL)        //从头到尾,输出蛇身     {         gotoxy(tail->x,tail->y);         color(14);         printf("★");       //输出蛇身,蛇身使用★组成         tail=tail->next;    //蛇头输出完毕,输出蛇头的下一位,一直输出到蛇尾     } }  /**  * 随机出现食物  */ void createfood() {     snake *food_1;     srand((unsigned)time(NULL));            //初始化随机数     food_1=(snake*)malloc(sizeof(snake));   //初始化food_1     while((food_1->x%2)!=0)                    //保证其为偶数,使得食物能与蛇头对其,然后食物会出现在网格线上     {         food_1->x=rand()%52+2;              //食物随机出现     }     food_1->y=rand()%24+1;     q=head;     while(q->next==NULL)     {         if(q->x==food_1->x && q->y==food_1->y) //判断蛇身是否与食物重合         {             free(food_1);               //如果蛇身和食物重合,那么释放食物指针             createfood();               //重新创建食物         }         q=q->next;     }     gotoxy(food_1->x,food_1->y);     food=food_1;     color(12);     printf("●");           //输出食物 }  /**  * 判断是否咬到了自己  */ int biteself() {     snake *self;            //定义self为蛇身上的一个节点     self=head->next;        //self是蛇头之外的蛇身上的节点     while(self!=NULL)     {         if(self->x==head->x && self->y==head->y)    //如果self和蛇身上的节点重合         {             return 1;       //返回1         }         self=self->next;     }     return 0; }  /**  * 设置蛇撞墙的情况  */ void cantcrosswall() {       if(head->x==0 || head->x==56 ||head->y==0 || head->y==26) //如果蛇头碰到了墙壁     {         endgamestatus=1;        //返回第一种情况         endgame();              //出现游戏结束界面     } } /**  *  加速,蛇吃到食物会自动提速,并且按F1会加速  */ void speedup() {     if(sleeptime>=50)     {         sleeptime=sleeptime-10;         add=add+2;     } } /**  *  加速,按F2会减速  */ void speeddown() {     if(sleeptime<350)               //如果时间间隔小于350     {         sleeptime=sleeptime+30;     //时间间隔加上30         add=add-2;                  //每吃一次食物的得分减2     } } /**  *  控制方向    问题:为什么要设置status,而不使用前两章中接收键盘按键的方法  */ void snakemove()    //蛇前进,上U,下D,左L,右R {     snake * nexthead;     cantcrosswall();     nexthead=(snake*)malloc(sizeof(snake));        //为下一步开辟空间     if(status==U)     {         nexthead->x=head->x;        //向上前进时,x坐标不动,y坐标-1         nexthead->y=head->y-1;         nexthead->next=head;         head=nexthead;         q=head;                 //指针q指向蛇头         if(nexthead->x==food->x && nexthead->y==food->y)    //如果下一个有食物 下一个位置的坐标和食物的坐标相同         {             while(q!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");       //原来食物的位置,从●换成★                 q=q->next;          //指针q指向的蛇身的下一位也执行循环里的操作             }             score=score+add;        //吃了一个食物,在总分上加上食物的分             speedup();             createfood();           //创建食物         }         else                                 {             while(q->next->next!=NULL)    //如果没遇到食物             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");           //蛇正常往前走,输出当前位置的蛇身                 q=q->next;              //继续输出整个蛇身             }             gotoxy(q->next->x,q->next->y);  //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置             color(3);             printf("■");             free(q->next);      //进行输出■之后,释放指向下一位的指针             q->next=NULL;       //指针下一位指向空         }     }     if(status==D)     {         nexthead->x=head->x;        //向下前进时,x坐标不动,y坐标+1         nexthead->y=head->y+1;         nexthead->next=head;         head=nexthead;         q=head;         if(nexthead->x==food->x && nexthead->y==food->y)  //有食物         {             while(q!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;             }             score=score+add;             speedup();             createfood();         }         else                               //没有食物         {             while(q->next->next!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;             }             gotoxy(q->next->x,q->next->y);             color(3);             printf("■");             free(q->next);             q->next=NULL;         }     }     if(status==L)     {         nexthead->x=head->x-2;        //向左前进时,x坐标向左移动-2,y坐标不动         nexthead->y=head->y;         nexthead->next=head;         head=nexthead;         q=head;         if(nexthead->x==food->x && nexthead->y==food->y)//有食物         {             while(q!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;             }             score=score+add;             speedup();             createfood();         }         else                                //没有食物         {             while(q->next->next!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;                     }             gotoxy(q->next->x,q->next->y);             color(3);             printf("■");             free(q->next);             q->next=NULL;         }     }     if(status==R)     {         nexthead->x=head->x+2;        //向右前进时,x坐标向右移动+2,y坐标不动         nexthead->y=head->y;         nexthead->next=head;         head=nexthead;         q=head;         if(nexthead->x==food->x && nexthead->y==food->y)//有食物         {             while(q!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;             }             score=score+add;             speedup();             createfood();         }         else                                         //没有食物         {             while(q->next->next!=NULL)             {                 gotoxy(q->x,q->y);                 color(14);                 printf("★");                 q=q->next;                     }             gotoxy(q->next->x,q->next->y);             color(3);             printf("■");             free(q->next);             q->next=NULL;         }     }     if(biteself()==1)       //判断是否会咬到自己     {         endgamestatus=2;         endgame();     } } /**  * 控制键盘按键  */ void keyboardControl() {     status=R;       //初始蛇向右移动     while(1)     {         scoreandtips();         if(GetAsyncKeyState(VK_UP) && status!=D)            //GetAsyncKeyState函数用来判断函数调用时指定虚拟键的状态         {             status=U;           //如果蛇不是向下前进的时候,按上键,执行向上前进操作         }         else if(GetAsyncKeyState(VK_DOWN) && status!=U)     //如果蛇不是向上前进的时候,按下键,执行向下前进操作         {             status=D;         }         else if(GetAsyncKeyState(VK_LEFT)&& status!=R)      //如果蛇不是向右前进的时候,按左键,执行向左前进         {             status=L;         }         else if(GetAsyncKeyState(VK_RIGHT)&& status!=L)     //如果蛇不是向左前进的时候,按右键,执行向右前进         {             status=R;         }         if(GetAsyncKeyState(VK_SPACE))        //按暂停键,执行pause暂停函数         {             while(1)             {                 Sleep(300); //sleep()函数,头文件#include <unistd.h>  另进程暂停,知道达到里面设定的参数的时间。                 if(GetAsyncKeyState(VK_SPACE))      //按空格键暂停                 {                     break;                 }             }                }         else if(GetAsyncKeyState(VK_ESCAPE))         {             endgamestatus=3;    //按esc键,直接到结束界面             break;         }         else if(GetAsyncKeyState(VK_F1))    //按F1键,加速         {             speedup();         }         else if(GetAsyncKeyState(VK_F2))    //按F2键,减速         {             speeddown();         }         Sleep(sleeptime);         snakemove();     } } /**  * 储存最高分进文件  */ void File_in() {     FILE *fp;     fp = fopen("save.txt", "w+");       //以读写的方式建立一个名为save.txt的文件     fprintf(fp, "%d", score);           //把分数写进文件中     fclose(fp);                         //关闭文件 } /**  * 在文件中读取最高分  */ void File_out() {     FILE *fp;     fp = fopen("save.txt", "a+");       //打开文件save.txt     fscanf(fp, "%d", &HighScore);       //把文件中的最高分读出来     fclose(fp);                         //关闭文件 } /* *   游戏说明 */ void explation() {     int i,j = 1;     system("cls");     color(13);     gotoxy(44,3);     printf("游戏说明");     color(2);     for (i = 6; i <= 22; i++)   //输出上下边框===     {         for (j = 20; j <= 75; j++)  //输出左右边框||         {             gotoxy(j, i);             if (i == 6 || i == 22) printf("=");             else if (j == 20 || j == 75) printf("||");         }     }     color(3);     gotoxy(30,8);     printf("tip1: 不能撞墙,不能咬到自己");     color(10);     gotoxy(30,11);     printf("tip2: 用↑.↓.←.→分别控制蛇的移动");     color(14);     gotoxy(30,14);     printf("tip3: F1 为加速,F2 为减速");     color(11);     gotoxy(30,17);     printf("tip4: 按空格键暂停游戏,再按空格键继续");     color(4);     gotoxy(30,20);     printf("tip5: Esc :退出游戏");     getch();                //按任意键返回主界面     system("cls");     printsnake();     welcometogame(); } /**  * 结束游戏  */ void endgame() {     system("cls");     if(endgamestatus==1)     {         Lostdraw();         gotoxy(35,9);         color(12);         printf("对不起,您撞到墙了。游戏结束!");     }     else if(endgamestatus==2)     {         Lostdraw();         gotoxy(35,9);         color(12);         printf("对不起,您咬到自己了。游戏结束!");     }     else if(endgamestatus==3)     {         Lostdraw();         gotoxy(40,9);         color(12);         printf("您已经结束了游戏。");     }     gotoxy(43,12);     color(13);     printf("您的得分是 %d",score);     if(score >= HighScore)     {         color(10);         gotoxy(33,16);         printf("创纪录啦!最高分被你刷新啦,真棒!!!");         File_in();              //把最高分写进文件     }     else     {         color(10);         gotoxy(33,16);         printf("继续努力吧~ 你离最高分还差:%d",HighScore-score);     }     choose(); } /**  * 边框下面的分支选项  */ void choose() {     int n;     gotoxy(25,23);     color(12);     printf("我要重新玩一局-------1");     gotoxy(52,23);     printf("不玩了,退出吧-------2");     gotoxy(46,25);     color(11);     printf("选择:");     scanf("%d", &n);     switch (n)     {     case 1:         system("cls");          //清屏         score=0;                //分数归零         sleeptime=200;            //设定初始速度         add = 10;                //使add设定为初值,吃一个食物得分10,然后累加         printsnake();           //返回欢迎界面         welcometogame();         break;     case 2:         exit(0);                //退出游戏         break;     default:         gotoxy(35,27);         color(12);         printf("※※您的输入有误,请重新输入※※");         system("pause >nul");         endgame();         choose();         break;     } } /**  * 失败界面  */ void Lostdraw() {     system("cls");     int i;     gotoxy(45,2);     color(6);     printf("\\\\\\|///");     gotoxy(43,3);     printf("\\\\");     gotoxy(47,3);     color(15);     printf(".-.-");     gotoxy(54,3);     color(6);     printf("//");     gotoxy(44,4);     color(14);     printf("(");     gotoxy(47,4);     color(15);     printf(".@.@");     gotoxy(54,4);     color(14);     printf(")");     gotoxy(17,5);     color(11);     printf("+------------------------");     gotoxy(35,5);     color(14);     printf("oOOo");     gotoxy(39,5);     color(11);     printf("----------");     gotoxy(48,5);     color(14);     printf("(_)");     gotoxy(51,5);     color(11);     printf("----------");     gotoxy(61,5);     color(14);     printf("oOOo");     gotoxy(65,5);     color(11);     printf("-----------------+");     for(i = 6;i<=19;i++)        //竖边框     {         gotoxy(17,i);         printf("|");         gotoxy(82,i);         printf("|");     }     gotoxy(17,20);     printf("+---------------------------------");     gotoxy(52,20);     color(14);     printf("☆☆☆〃");     gotoxy(60,20);     color(11);     printf("----------------------+"); } /** * 主函数 */ int main() {         system("mode con cols=100 lines=30");   //设置控制台的宽高     printsnake();     welcometogame();     File_out();     keyboardControl();     endgame();     return 0; }

推荐阅读