【超详细C语言】带你吃透贪吃蛇游戏之精髓
文章目录
01. 开发背景
02. 功能介绍
03. 欢迎界面设计
3.1 常用终端控制函数
3.2 设置文本颜色函数
3.3 设置光标位置函数
3.4 绘制字符画(蛇)
3.5 欢迎界面函数
04. 游戏帮助界面设计
05. 退出游戏实现
06. 游戏逻辑
6.1 按下ESC键结束游戏
6.1 判断是否撞到墙
6.3 判断是否咬到自己
07. 游戏失败界面设计
7.1 游戏失败界面边框设计
7.2 撞墙失败界面
7.3 咬到蛇身失败界面
7.4 ESC结束游戏界面
7.5 界面添加选择
7.6 写文件实现
08. 一起来找茬
09. 项目扩展
10. 项目总结
01. 开发背景
贪吃蛇起源于西方,来自于蛇骗夏娃和亚当偷吃禁果的神话。人们为了说明蛇的一个“贪”字,开发出了贪吃蛇游戏。本公开课使用C语言开发一个贪吃蛇游戏。
贪吃蛇最初为人们所知的是诺基亚手机附带的一个小游戏,它伴随着诺基亚手机走向世界。现在的贪吃蛇出现了许多衍生版本,并被移植到各种平台上。
通过本案例的学习,大家可以学到:
Visual Studio 2017开发环境
C语言中的三大结构和函数
C语言中动态内存申请和释放
C语言中文件基本操作
C语言中的简单单向链表
控制终端基本设置和监听按键
C语言简单游戏开发流程
C语言简单游戏开发调试技巧
02. 功能介绍
贪吃蛇的游戏规则也很简单,具体为:蛇出现在封闭的空间中,同时在地图上会随机出现食物,玩家通过键盘上的上下左右方向键来控制蛇的前进方向。蛇头撞到食物,则食物消失,表示被蛇吃掉了,蛇身增加一节,增加玩家的得分。接着又随机出现一个食物,等待蛇来吃。如果蛇在前进的过程中撞到墙或者咬到蛇身或者玩家按下ESC键,则游戏退出。
项目演示
03. 欢迎界面设计
欢迎界面如下:
3.1 常用终端控制函数
SetConsoleTextAttribute函数介绍
BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput,WORD wAttributes);
功能:设置控制台文本属性(颜色),可以设置前景色FOREGROUND(文本颜色)和背景色BACKGROUND
SetConsoleTextAttribute官方文档介绍请参考网址:https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute
参考示例:
HANDLE hOut;hOut = GetStdHandle(STD_OUTPUT_HANDLE); /* 获取标注输出句柄 */
SetConsoleTextAttribute(hOut, FOREGROUND_BLUE); /* 设置控制台颜色,前景色为蓝色*/
SetConsoleTextAttribute(hOut, BACKGROUND_RED); /* 背景色为红色 */
SetConsoleCursorPosition函数介绍
BOOL SetConsoleCursorPosition(HANDLE hConsoleOutput, COORD dwCursorPosition);
功能:设置控制台光标坐标
SetConsoleCursorPosition官方文档介绍请参考网址:https://docs.microsoft.com/en-us/windows/console/setconsolecursorposition
参考示例:
COORD pos = {x, y};/* x是横坐标 y是纵坐标 */
HANDLE hOut;hOut = GetStdHandle(STD_OUTPUT_HANDLE); /* 获取标注输出句柄 */
SetConsoleCursorPosition(hOut,pos); /* 设置控制台光标坐标(设备句柄, 光标坐标) */
3.2 设置文本颜色函数
//设置终端字体颜色
int setColor(int c)
{//GetStdHandle: 获取指定的标准设备的句柄//STD_OUTPUT_HANDLE 标准输出句柄//c 颜色值SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);return 0;
}
十进制颜色对照表:
3.3 设置光标位置函数
//设置光标的坐标
int gotoXY(int x, int y)
{COORD c;//设置横坐标c.X = x;//设置纵坐标c.Y = y;//设置光标的位置SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);return 0;
}
3.4 绘制字符画(蛇)
参考代码:
//绘制字符画 --蛇
int printSnake(void)
{//清屏system("cls");gotoXY(35, 1);setColor(6);printf("/^\\/^\\"); //蛇眼睛gotoXY(34, 2);printf("|__| O|"); //蛇眼睛gotoXY(33, 2);setColor(2);printf("_");gotoXY(25, 3);setColor(12);printf("\\/"); //蛇信gotoXY(31, 3);setColor(2);printf("/");gotoXY(37, 3);setColor(6);printf(" \\_/"); //蛇眼睛gotoXY(41, 3);setColor(10);printf(" \\");gotoXY(26, 4);setColor(12);printf("\\____"); //舌头gotoXY(32, 4);printf("_________/");gotoXY(31, 4);setColor(2);printf("|");gotoXY(43, 4);setColor(10);printf("\\");gotoXY(32, 5);setColor(2);printf("\\_______"); //蛇嘴gotoXY(44, 5);setColor(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("~--______-~ ~-___-~");return 0;
}
测试代码如下:
int main()
{//设置控制台的宽高system("mode con cols=100 lines=30");printSnake();system("pause");return 0;
}
测试效果如下:
3.5 欢迎界面函数
界面设计分析:
参考代码:
//欢迎界面
int welcomGame(void)
{int i;int j;int n = 0;//绘制字符画蛇printSnake();//输出文字setColor(11);gotoXY(45, 18);printf("贪吃蛇游戏");setColor(14);//边框范围20--26行 27--74列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("|");}}}setColor(12);gotoXY(35, 22);printf("1. 开始游戏");gotoXY(55, 22);printf("2. 游戏说明");gotoXY(35, 24);printf("3. 退出游戏");gotoXY(27, 27);printf("请选择[1 2 3]: ");scanf("%d", &n);//清空换行符getchar();return n;
}
主函数参考代码如下:
int main()
{int choice;//设置控制台的宽高system("mode con cols=100 lines=30");while (1){choice = welcomGame();switch (choice){//开始游戏case 1:printf("开始游戏");break;//游戏说明case 2:printf("游戏说明");break;//退出游戏case 3:break;default:setColor(12);gotoXY(45, 28);printf("请做出有效选择[1~3]");//输入任意键getchar();}}system("pause");return 0;
}
04. 游戏帮助界面设计
游戏说明模块如下:
游戏帮助界面参考代码:
//游戏帮助界面
int aboutGame(void)
{int i = 0;int j = 0;//清屏system("cls");setColor(13);gotoXY(44, 3);printf("游戏说明");setColor(2);//画出边框//6~22行 20~75列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("||");}}}setColor(3);gotoXY(30, 8);printf("★ 1.不能撞到墙壁,不能咬到自己");setColor(5);gotoXY(30, 11);printf("★ 2.F1加速前进,F2减速前进");setColor(11);gotoXY(30, 14);printf("★ 3.使用空格暂停游戏和继续游戏");setColor(13);gotoXY(30, 17);printf("★ 4.使用方向键控制前进的方向");setColor(14);gotoXY(30, 20);printf("★ 5.按下ESC键退出游戏");setColor(12);gotoXY(22, 24);printf("按下回车键返回主界面...");getchar();return 0;
}
主函数代码修改如下:
int main()
{int choice;//设置控制台的宽高system("mode con cols=100 lines=30");while (1){choice = welcomGame();switch (choice){//开始游戏case 1:printf("开始游戏");break;//游戏说明case 2:aboutGame();break;//退出游戏case 3:break;default:setColor(12);gotoXY(45, 28);printf("请做出有效选择[1~3]");//输入任意键getchar();}}system("pause");return 0;
}
05. 退出游戏实现
在主菜单中, 当用户选择3的时候,直接退出游戏
在主函数case 3中添加如下代码:
//退出游戏
case 3:exit(0);break;
06. 游戏逻辑
6.1 按下ESC键结束游戏
在moveKeyControl函数中添加如下代码片段
//按下F2减速
if (GetAsyncKeyState(VK_F2))
{speedDown();
}//按下ESC键 结束游戏
if (GetAsyncKeyState(VK_ESCAPE))
{endStatus = 3;break;
}
6.2 判断是否撞到墙
参考代码:
//判断是否撞墙
int isHitWall(void)
{if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26){return 1;}
}
在snake.c文件moveKeyControl函数中添加如下代码:
Sleep(sleepTime);moveSnake();//判断是否撞墙
if (isHitWall())
{endStatus = 1;break;
}
6.3 判断是否咬到自己
//判断是否咬到自己
int isBitSelf(void)
{snake_t *tmp = NULL;tmp = head->next;while (NULL != tmp){if (tmp->x == head->x && tmp->y == head->y){return 1;}tmp = tmp->next;}return 0;
}
在snake.c文件moveKeyControl函数中添加如下代码:
//判断是否撞墙if (isHitWall()){endStatus = 1;break;}//判断是否咬到自己if (isBitSelf()){endStatus = 2;break;}
07. 游戏失败界面设计
7.1 游戏失败界面边框设计
游戏边框失败界面分析:
参考源代码:
//游戏失败界面边框
void failGameUi(void)
{int i;system("cls");//显示游戏失败提示setColor(12);gotoXY(44, 3);printf("游 戏 失 败!!!");setColor(11);gotoXY(17, 5);//绘制上边框printf("+----------------------------------------------------------------+");//绘制下边框gotoXY(17, 20);printf("+----------------------------------------------------------------+");//绘制左右边框for (i = 6; i < 20; i++){gotoXY(17, i);printf("|");gotoXY(82, i);printf("|");}
}
在moveKeyControl函数中按下ESC选项中添加如下代码:
//按下ESC键 结束游戏
if (GetAsyncKeyState(VK_ESCAPE))
{endStatus = 3;failGameUi();break;
}
7.2 撞墙失败界面
显示效果如下:
界面分析:
参考代码:
//结束游戏
int endGame(void)
{int n;int highScore;//显示游戏失败边框failGameUi();setColor(12);//根据不同的状态显示不同的失败提示switch (endStatus){//撞到墙case 1:gotoXY(38, 9);printf("您撞到墙了,游戏结束!!!");break;//咬到自己case 2:break;//用户按下ESC退出case 3:break;default:;}//显示您的得分gotoXY(43, 12);setColor(13);printf("您的得分: %d", score);//从文件中读取最高分highScore = readFile();if (score > highScore){setColor(10);gotoXY(38, 16);printf("恭喜你, 你已经创记录了,");//写文件//writeFile(score);}else{setColor(10);gotoXY(38, 16);printf("加油哦,离最高分还差%d分", highScore - score);}return 0;
}
7.3 咬到蛇身失败界面
显示效果如下:
在endGame函数中修改代码如下:
//结束游戏
int endGame(void)
{int n;int highScore;//显示游戏失败边框failGameUi();setColor(12);gotoXY(38, 9);//根据不同的状态显示不同的失败提示switch (endStatus){//撞到墙case 1:printf("您撞到墙了,游戏结束!!!");break;//咬到自己case 2:printf("您咬到蛇身了,游戏结束!");break;//用户按下ESC退出case 3:break;default:;}//显示您的得分gotoXY(43, 12);setColor(13);printf("您的得分: %d", score);//从文件中读取最高分highScore = readFile();if (score > highScore){setColor(10);gotoXY(38, 16);printf("恭喜你, 你已经创记录了,");//写文件//writeFile(score);}else{setColor(10);gotoXY(38, 16);printf("加油哦,离最高分还差%d分", highScore - score);}return 0;
}
7.4 ESC结束游戏界面
显示效果:
在endGame函数中修改代码如下:
//结束游戏
int endGame(void)
{int n;int highScore;//显示游戏失败边框failGameUi();setColor(12);gotoXY(38, 9);//根据不同的状态显示不同的失败提示switch (endStatus){//撞到墙case 1:printf("您撞到墙了,游戏结束!!!");break;//咬到自己case 2:printf("您咬到蛇身了,游戏结束!");break;//用户按下ESC退出case 3:printf("您已经结束了游戏,游戏结束");break;default:;}//显示您的得分gotoXY(43, 12);setColor(13);printf("您的得分: %d", score);//从文件中读取最高分highScore = readFile();if (score > highScore){setColor(10);gotoXY(38, 16);printf("恭喜你, 你已经创记录了,");//写文件//writeFile(score);}else{setColor(10);gotoXY(38, 16);printf("加油哦,离最高分还差%d分", highScore - score);}return 0;
}
7.5 界面添加选择
显示效果如下:
界面分析:
代码实现:
//结束游戏
int endGame(void)
{int n;int highScore;while (1){//显示游戏失败边框failGameUi();setColor(12);gotoXY(38, 9);//根据不同的状态显示不同的失败提示switch (endStatus){//撞到墙case 1:printf("您撞到墙了,游戏结束!!!");break;//咬到自己case 2:printf("您咬到蛇身了,游戏结束!");break;//用户按下ESC退出case 3:printf("您已经结束了游戏,游戏结束");break;default:;}//显示您的得分gotoXY(43, 12);setColor(13);printf("您的得分: %d", score);//从文件中读取最高分highScore = readFile();if (score > highScore){setColor(10);gotoXY(38, 16);printf("恭喜你, 你已经创记录了,");//写文件//writeFile(score);}else{setColor(10);gotoXY(38, 16);printf("加油哦,离最高分还差%d分", highScore - score);}//输出用户选择信息gotoXY(25, 23);setColor(12);printf("在玩一局请输入: 1");gotoXY(52, 23);printf("直接退出请输入:2");gotoXY(46, 25);setColor(11);printf("请选择:");scanf("%d", &n);getchar();if (1 == n){score = 0;sleepTime = 350;add = 1;break;}else if (2 == n){exit(0);}else{gotoXY(30, 27);setColor(12);printf("您的输入有误, 请重新输入, 按下任意键继续");getchar();}}return 0;
}
7.6 写文件实现
//写文件
int writeFile(int score)
{FILE *fp = NULL;fp = fopen("save.txt", "w+");fprintf(fp, "%d", score);fclose(fp);return 0;
}
在endGame函数中,如果破纪录了就写文件
if (score > highScore)
{setColor(10);gotoXY(38, 16);printf("恭喜你, 你已经创记录了,");//写文件writeFile(score);
}
08. 一起来找茬
//销毁蛇
int destroySnake(void)
{snake_t *tmp = NULL;snake_t *save = NULL;tmp = head;while (NULL != tmp){save = tmp->next;free(tmp);tmp = save;}head = NULL;return 0;
}
09. 项目扩展
设置关卡
蛇移动速度
保存每一个用户的得分信息
排名榜
10. 项目总结
基础知识:C语言 数据结构中简单单向链表
推荐阅读
(点击标题可跳转阅读)
I2c串行总线组成及其工作原理
const 指针与指向const的指针
蜕变成蝶~Linux设备驱动之字符设备驱动
24小时学通Linux内核--内核探索工具类
队列及其实现
机器学习理论提升方法AdaBoost算法第一卷
C++小游戏:扑克牌21点
C语言main函数有哪些写法呢
关注公众号【技术让梦想更伟大】,获取更多Linux/C/C++/Python/FPGA等原创技术文章。后台免费获取经典电子书籍和视频资源,实时更新,原创不易,请多支持,谢谢!
【超详细C语言】带你吃透贪吃蛇游戏之精髓相关推荐
- 计算机课程编程设计贪吃蛇游戏设计,c语言课程设计报告--贪吃蛇游戏系统
c语言课程设计报告--贪吃蛇游戏系统 院 系 计算机科学技术学院 班 级 组 长 学 号 指导教师 2017 年 3 月 2 日 C 语言语言基础课程设计基础课程设计 贪贪贪贪吃吃吃吃蛇蛇蛇蛇游游游游 ...
- 完整版! 大一新手C语言数据结构实现简单贪吃蛇游戏
大一新手C语言数据结构实现简单贪吃蛇游戏含源代码 贪吃蛇 1.前言简述 2.编写语言及工具 3.游戏的头文件代码(.h) 3.1map.h 3.2snake.h 3.3Food.h 4.游戏的源文件代 ...
- 使用C语言gtk编程一个贪吃蛇游戏设计与实现
使用C语言以及gtk编程设计一个贪吃蛇游戏. 功能需求: (1)窗口界面设计:创建各种窗口和按钮标签等: (2)小蛇移动控制:按键盘上的上下左右键控制小蛇上下左右移动: (3)游戏进程控制:若小蛇碰到 ...
- C语言打飞机、贪吃蛇游戏
打飞机游戏 学习一个语言最快的方法就是从游戏开始. One:(操作性较慢) #include "stdio.h" #include <windows.h> #inclu ...
- 用C语言制作一款多人贪吃蛇游戏
上学期学的C语言,寒假想用来做点好玩的东西而不是单纯应付考试,刚开始想到了贪吃蛇,最后做成了双贪吃蛇,双龙夺猪讲的是随着猪肉价格渐长,一条龙与一条蛇争夺猪肉的故事233333 代码使用了easyx图形 ...
- 超详细c语言简化tcp通信接口(多线程实现一个服务端处理多个客户端服务)
超详细c语言tcp通信接口 1.可下载源码(客户端 || 服务端通信) 2.说明 3.接口代码 4.客户端通信main_client_demo.c 5.服务端通信main_server_demo.c ...
- [C语言] 自制的贪吃蛇游戏
使用C语言自带的游戏图新库开发贪吃蛇 我看网上好多制作贪吃蛇的帖子都是对刚学习C语言的同学们很不友好,制作的都是控制台,黑窗口的贪吃蛇游戏,能做出来但是感觉很无趣,不太像正常的游戏,接下来我将制作完全 ...
- C语言写个贪吃蛇游戏
贪吃蛇是个非常经典的游戏,用C语言来实现也是一个好玩的事情.这个游戏我写完后放在知乎,竟然点赞的人数超级多.我觉得大家喜欢,一个方面是因为写得简单,大家都能看得懂,一个可扩展性还是非常强的. 我试了说 ...
- linux贪吃蛇c程序,Linux环境下C语言实现贪吃蛇游戏
Linux环境下C语言实现贪吃蛇游戏 [liul@test snake]$ more snake.c #include #include #include #include #include #def ...
最新文章
- redis的持久化方式有哪些?
- MySQL事务的回滚
- 面试:你说一下 MyBatis 事务吧!
- hdfs合并块_hdfs 小文件合并 问题
- html JSP 富文本案例,JSP页面引入Ueditor富文本编辑器!
- 如果你的Spring水平就这?求求就不要去面试官那里送人头了
- Docker学习三:Docker 数据管理
- Google 击败苹果!| 极客头条
- js 字符串换行_JS代码编程中经常用到的超长字符串换行方法,你最喜欢哪一种?
- Bex5文档服务器,WeX5/BeX5 UIServer的缓存机制
- Zabbix 5.0版本的详细安装教程
- 数据分析实战(五)基于R语言的Kmean聚类分析实战
- 基于AntDesign组件的Vue项目
- MultiButton | 一个小巧简单易用的事件驱动型按键驱动模块
- [JT]攻防世界web专项qwq
- QT pro中加入文件拷贝方法
- 2020年12月电子学会Python等级考试试卷(一级)考题解析
- Unity 【Content Size Fitter】- 聊天气泡自动适配Text文本框大小
- java读取文本文件,并且去除重复字段
- 开源GIS浅谈 【转】