最近无事开始用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();
- }