最近无事开始用C语言写一些小游戏小游戏程序,这个贪吃蛇当然是经典中的经典,所以先开始写。
文件引用#include<redio.h>//输入输出#include<time.h>//用于获取随机数 #include<windows.h>//控制DOS界面 #include<stdlib.h>//定义了一些宏和通用工具函数 #include<conio.h> // 接收键盘输入输出
复制代码 /**************************函数声明***************************/ void gotoxy(int x,int y); //设置光标位置 int color(int c); //更改文字颜色 void printsnake(); //字符画--蛇 void welcome(); //开始界面 void createMap(); //绘制地图 void scoreandtips(); //游戏界面右侧的积分和小提示 void initsnake(); //初始化蛇身,花蛇身 void createfood(); //创建并随机出现食物 int biteself(); //判断是否咬到自己 void cantcrosswall(); //设置蛇撞到墙的情况 void speedup(); //加速 void speeddown(); //减速 void snakemove(); //控制蛇前进方向 void keyjianpan(); //控制键盘按键 void Lostdraw(); //游戏结束界面 void endgame(); //游戏结束 void choose(); //游戏失败之后的选择 void File_out(); //在文件中读取最高分 void File_in(); //储存最高分文件 void explation(); //游戏说明
复制代码/********************游戏欢迎界面***********************/int color(int c) //颜色函数 { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);//更改文字颜色 return 0; } void gotoxy(int x,int y) //设置光标位置 { COORD c; c.X=x; c.Y=y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c); } void printsnake() { int i,j=10; gotoxy(37,21); color(14); printf(" 张 洋 贪 吃 蛇\n 欢 迎 你!"); gotoxy(19-1,9); color(12); printf("张洋"); gotoxy(23-1,9); color(12); printf("张洋"); gotoxy(27-1,9); color(12); printf("张洋"); gotoxy(27-1,11); color(12); printf("张洋"); gotoxy(19-1,13); color(12); printf("张洋"); gotoxy(23-1,13); color(12); printf("张洋"); gotoxy(27-1,13); color(12); printf("张洋"); for(i=20;i<28;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j++; } for(i=30;i<38;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j--; } for(i=40;i<48;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j++; } for(i=50;i<58;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j--; } for(i=60;i<68;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j++; } for(i=70;i<77;i++) { gotoxy(i+10,j); color(j-10); printf("张洋"); j--; } gotoxy(87,11); color(11); printf("张洋"); gotoxy(91,11); color(11); printf("张洋"); gotoxy(95,11); color(11); printf("张洋"); gotoxy(99,11); color(11); printf("张洋"); } /*************************主函数******************************************/ int main() { system("mode con cols=140 lines=40");//设置控制台的宽高 printsnake();//绘制字符蛇 return 0; }
复制代码
/************************* 每个人可根据自己的创意,设计不同的欢迎界面。 **********************/
/************************************************ 开始界面 ********************************************/
void welcome(){ int n; int i,j=1; color(14); for (i=24;i<=30;i++) { for (j=35;j<=82;j++) { gotoxy(j,i); if(i==24||i==30) { printf("-"); } else if(j==35||j==82) { printf("|"); } } } color(12); gotoxy(45,26); printf("1.开始游戏"); gotoxy(65,26); printf("2.游戏说明"); gotoxy(45,28); printf("3.退出游戏"); gotoxy(48,32); color(3); printf("请选择[1 2 3]:[ ]\b\b"); color(14); scanf("%d",&n); switch(n) { case 1 : system("cls");//清屏 break; case 2: break; case 3: exit(0); break; default: color(12); gotoxy(40,38); printf("请输入1-3之间的数!"); getch(); //输入任意键 system("cls"); //清屏 printsnake(); welcome(); } } int main() { system("mode con cols=140 lines=40");//设置控制台的宽高 printsnake();//绘制字符蛇 welcome(); return 0; }
复制代码
两个结合在一起,就构成了开始的主界面

游戏主窗体设计
/****************************游戏主窗体设计*********************************/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("■\n\n"); } } } /*********************游戏右侧的得分和小提示******************/ void scoreandtips() { int i; File_out(); //调用File_out(),读取文件中的内容 gotoxy(74,4); color(11); printf("▂▄▅最高纪录▄▃▂:%d",HighScore);//打印游戏最高分 gotoxy(74,8); color(14); printf("得分: %d ",score); color(13); gotoxy(83,11); printf("小 提 示"); gotoxy(70,13); color(6); printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"); for (i=15;i<25;i=i+2) { gotoxy(70,i); printf("┃"); } for (i=15;i<25;i=i+2) { gotoxy(103,i); printf("┃"); } gotoxy(70,25); printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"); color(3); gotoxy(74,14); printf("每个事物得分:%d 分",add); gotoxy(74,16); printf("不能穿墙,不能咬到自己"); gotoxy(74,18); printf("用↑↓←→分别控制蛇的移动"); gotoxy(74,20); printf("F1加速,F2减速"); gotoxy(74,22); printf("space:暂停游戏"); gotoxy(74,24); printf("ESC:退出游戏"); } /***************在文件中读取最高分*******************/ void File_out() { FALSE *fp; fp=fopen("save.txt","a+"); //打开文件save.txt fscanf(fp,"%d",&HighScore); fclose(fp); } /*****************主函数****************************/ int main() { system("mode con cols=120 lines=40");//设置控制台的宽高 printsnake();//绘制字符蛇 welcome();//欢迎界面 File_out(); return 0; }
复制代码
在C语言中的文件调用,保存一定要学好,才能在这里灵活运用。
绘制蛇身和蛇食物
/******************* 绘制蛇身************************/ 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; //设置食物的X坐标随机出现,食物的x坐标在2-53 } food_1->y=rand()%24+1; //食物的Y坐标在1-24 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; //返回第一种情况 } } /*******************设置蛇加速前进**********/ void speedup() { if (sleeptime>=50) //如果时间间隔大于等于50 { sleeptime=sleeptime-10; //时间间隔减10 add=add+2; //每吃一次食物的得分加2 if(sleeptime==320) { add=2; //防止减到1之后再加回来有错 } } } /*******************设置蛇减速前进************/ void speeddown() { if (sleeptime<350) //如果时间间隔小于350 { sleeptime=sleeptime+30; //时间间隔加上30 add=add-2; //没吃一次食物的得分减2 if (sleeptime==350) { add=1; //保证最低分为1 } } } /******************控制方向*************************/ void snakemove() { snake *nexthead; cantcrosswall(); nexthead=(snake*)malloc(sizeof(snake)); //为下一步开辟空间 if (status==W) { nexthead->x=head->x; //向上前进时,x坐标不变,y坐标-1 nexthead->y=head->y-1; nexthead->next=head; 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; //继续输出整个蛇身 } //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置 gotoxy(q->next->x,q->next->y); color(3); printf("■"); free(q->next); //进行输出▼之后,释放指向下一位的指针 q->next=NULL; //指针下一位指向空 } } /// if (status==S) { nexthead->x=head->x; //向上前进时,x坐标不变,y坐标+1 nexthead->y=head->y+1; nexthead->next=head; 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; //继续输出整个蛇身 } //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置 gotoxy(q->next->x,q->next->y); color(3); printf("■"); free(q->next); //进行输出▼之后,释放指向下一位的指针 q->next=NULL; //指针下一位指向空 } } / if (status==A) { nexthead->x=head->x-2; //向左前进时,x坐标向左移动-2,y坐标不变 nexthead->y=head->y; nexthead->next=head; 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; //继续输出整个蛇身 } //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置 gotoxy(q->next->x,q->next->y); color(3); printf("■"); free(q->next); //进行输出▼之后,释放指向下一位的指针 q->next=NULL; //指针下一位指向空 } } / if (status==D) { nexthead->x=head->x+2; //向右前进时,x坐标向左移动+2,y坐标不变 nexthead->y=head->y; nexthead->next=head; 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; //继续输出整个蛇身 } //经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置 gotoxy(q->next->x,q->next->y); color(3); printf("■"); free(q->next); //进行输出▼之后,释放指向下一位的指针 q->next=NULL; //指针下一位指向空 } } if (biteself()==1) //判断是否会咬到自己 { endgamestatus=2; } } /******************************* 键盘 ************************************/ void key() { status=R; //初始蛇向右移动 while (1) { scoreandtips(); //游戏界面右侧的得分和小提醒 //GetAsyncKeyState函数 用来判断函数调用时指定虚拟键的状态 if (GetAsyncKeyState(VK_UP)&&status!=S) { status=W; //如果蛇不是向下前进的时候,按向上键,执行向上前进操作 } else if (GetAsyncKeyState(VK_DOWN)&&status!=W) { status=S; //如果蛇不是向上前进的时候,按向下键,执行向下前进操作 } else if (GetAsyncKeyState(VK_LEFT)&&status!=D) { status=A; //如果蛇不是向右前进的时候,按向左键,执行向左前进操作 } else if (GetAsyncKeyState(VK_RIGHT)&&status!=A) { status=D; //如果蛇不是向左前进的时候,按向右键,执行向右前进操作 } if (GetAsyncKeyState(VK_SPACE)) //按下暂停键,执行pause暂停函数 { while (1) { //Sleep()函数,头文件#include <unistd.h>另进程暂停,直到达到里面设定参数的时间 Sleep(300); 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,减速 { if (sleeptime<350) //如果时间间隔小于350 { sleeptime=sleeptime+30; //时间间隔加上30 add=add-2; //没吃一次食物的得分减2 if (sleeptime==350) { add=1; //保证最低分为1 } } } Sleep(sleeptime); //不按键时,蛇保持前行 snakemove(); } } /*****************主函数****************************/ int main() { system("mode con cols=120 lines=40"); //设置控制台的宽高 printsnake(); //绘制字符蛇 welcome(); //欢迎界面 File_out(); key(); return 0; }
复制代码/************************失败界面*********************/void Lostdraw() { int k; system("cls"); gotoxy(50,2); printf("∑游戏结果"); gotoxy(17,5); color(11); printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"); for (k=7;k<=18;k++) //竖边框 { gotoxy(17,k); printf("┃"); gotoxy(82,k); printf("┃"); } gotoxy(17,20); printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"); } /****************************结束游戏*****************/ 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) //如果按ESC键退出 { Lostdraw(); gotoxy(40,9); color(12); printf("你已经结束了游戏!"); } gotoxy(43,12); color(13); printf("你的得分是 %d",score); if (score>=HighScore) { color(10); gotoxy(40,16); printf("牛逼,创纪录了!!"); File_in(); //把最高分写进文件 } else //如果低于最高分 { color(10); gotoxy(35,16); printf("继续努力啊,你离最高分还差:%d",HighScore-score); } choose(); //边框下面的分支选项 } /********************边框下面的分支选项************/ void choose() { int m; gotoxy(25,23); color(12); printf("我要重新玩一把-------- 1"); gotoxy(52,23); printf("不玩了,退出-------- 2"); gotoxy(46,25); color(11); printf("选择: "); scanf("%d",&m); switch(m) { case 1: system("cls"); //清屏 score=0; //分数归零 sleeptime=200; //设定初始速度 add=10; //使add设为初值,吃一个食物得十分,然后累加 printsnake(); //返回欢迎界面 welcome(); break; case 2: exit(0); //退出游戏 break; default: //输入1或2以外的数字 gotoxy(35,27); color(12); printf("不要瞎输入,请重新输入"); system("pause>nul"); //按任意键 endgame(); choose(); //边框下面的分支语句 break; } } /*****************主函数****************************/ int main() { system("mode con cols=120 lines=40"); //设置控制台的宽高 printsnake(); //绘制字符蛇 welcome(); //欢迎界面 File_out(); //读取文件信息 keyjianpan(); //控制键盘按键 endgame(); //游戏结束 return 0; }
复制代码

游戏说明
/*********************游戏说明************************/void explation() { int i,j=1; system("cls"); color(13); gotoxy(52,3); printf("游戏说明"); color(2); for (i=6;i<=22;i++) //输出上下边框 { for (j=20;j<=75;j++) { gotoxy(j+10,i); if (i==6||i==22) { printf("||"); } } } color(3); gotoxy(40,8); printf("一:不能穿墙,不能咬到自己"); color(10); gotoxy(40,11); printf("二:用↑↓←→分别控制蛇的移动"); color(14); gotoxy(40,14); printf("三:F1加速,F2减速"); color(11); gotoxy(40,17); printf("四:安空格键暂停,再按空格键继续"); color(4); gotoxy(40,20); printf("五:ESC:退出游戏,space:暂停游戏"); getch();//按任意键返回主界面 system("cls"); printsnake(); welcome(); }
复制代码