文章目录

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语言】带你吃透贪吃蛇游戏之精髓相关推荐

  1. 计算机课程编程设计贪吃蛇游戏设计,c语言课程设计报告--贪吃蛇游戏系统

    c语言课程设计报告--贪吃蛇游戏系统 院 系 计算机科学技术学院 班 级 组 长 学 号 指导教师 2017 年 3 月 2 日 C 语言语言基础课程设计基础课程设计 贪贪贪贪吃吃吃吃蛇蛇蛇蛇游游游游 ...

  2. 完整版! 大一新手C语言数据结构实现简单贪吃蛇游戏

    大一新手C语言数据结构实现简单贪吃蛇游戏含源代码 贪吃蛇 1.前言简述 2.编写语言及工具 3.游戏的头文件代码(.h) 3.1map.h 3.2snake.h 3.3Food.h 4.游戏的源文件代 ...

  3. 使用C语言gtk编程一个贪吃蛇游戏设计与实现

    使用C语言以及gtk编程设计一个贪吃蛇游戏. 功能需求: (1)窗口界面设计:创建各种窗口和按钮标签等: (2)小蛇移动控制:按键盘上的上下左右键控制小蛇上下左右移动: (3)游戏进程控制:若小蛇碰到 ...

  4. C语言打飞机、贪吃蛇游戏

    打飞机游戏 学习一个语言最快的方法就是从游戏开始. One:(操作性较慢) #include "stdio.h" #include <windows.h> #inclu ...

  5. 用C语言制作一款多人贪吃蛇游戏

    上学期学的C语言,寒假想用来做点好玩的东西而不是单纯应付考试,刚开始想到了贪吃蛇,最后做成了双贪吃蛇,双龙夺猪讲的是随着猪肉价格渐长,一条龙与一条蛇争夺猪肉的故事233333 代码使用了easyx图形 ...

  6. 超详细c语言简化tcp通信接口(多线程实现一个服务端处理多个客户端服务)

    超详细c语言tcp通信接口 1.可下载源码(客户端 || 服务端通信) 2.说明 3.接口代码 4.客户端通信main_client_demo.c 5.服务端通信main_server_demo.c ...

  7. [C语言] 自制的贪吃蛇游戏

    使用C语言自带的游戏图新库开发贪吃蛇 我看网上好多制作贪吃蛇的帖子都是对刚学习C语言的同学们很不友好,制作的都是控制台,黑窗口的贪吃蛇游戏,能做出来但是感觉很无趣,不太像正常的游戏,接下来我将制作完全 ...

  8. C语言写个贪吃蛇游戏

    贪吃蛇是个非常经典的游戏,用C语言来实现也是一个好玩的事情.这个游戏我写完后放在知乎,竟然点赞的人数超级多.我觉得大家喜欢,一个方面是因为写得简单,大家都能看得懂,一个可扩展性还是非常强的. 我试了说 ...

  9. linux贪吃蛇c程序,Linux环境下C语言实现贪吃蛇游戏

    Linux环境下C语言实现贪吃蛇游戏 [liul@test snake]$ more snake.c #include #include #include #include #include #def ...

最新文章

  1. redis的持久化方式有哪些?
  2. MySQL事务的回滚
  3. 面试:你说一下 MyBatis 事务吧!
  4. hdfs合并块_hdfs 小文件合并 问题
  5. html JSP 富文本案例,JSP页面引入Ueditor富文本编辑器!
  6. 如果你的Spring水平就这?求求就不要去面试官那里送人头了
  7. Docker学习三:Docker 数据管理
  8. Google 击败苹果!| 极客头条
  9. js 字符串换行_JS代码编程中经常用到的超长字符串换行方法,你最喜欢哪一种?
  10. Bex5文档服务器,WeX5/BeX5 UIServer的缓存机制
  11. Zabbix 5.0版本的详细安装教程
  12. 数据分析实战(五)基于R语言的Kmean聚类分析实战
  13. 基于AntDesign组件的Vue项目
  14. MultiButton | 一个小巧简单易用的事件驱动型按键驱动模块
  15. [JT]攻防世界web专项qwq
  16. QT pro中加入文件拷贝方法
  17. 2020年12月电子学会Python等级考试试卷(一级)考题解析
  18. Unity 【Content Size Fitter】- 聊天气泡自动适配Text文本框大小
  19. java读取文本文件,并且去除重复字段
  20. 开源GIS浅谈 【转】

热门文章

  1. 自动驾驶-PID控制器
  2. 外卖点餐APP-02(后台--员工管理)
  3. 《统计学习方法》——李航 学习大纲
  4. layui 文件上传(upload)实例重载及重新上传
  5. 毕业不要做新媒体短视频运营
  6. 微软推出“2020行业深耕升级计划”
  7. java 多线程 返回值_JAVA多线程实现和应用总结:如何使用有返回值的多线程
  8. 猎豹移动(金山网络)2015校园招聘(c++工程师)
  9. 单片机的工程建立模板
  10. vue里面的el只能绑定id吗_VUE初级教程详解