贪吃蛇小游戏(c语言)

1.效果展示

屏幕录制 2024-04-28 205129

2.基本功能

贪吃蛇地图绘制
蛇吃食物的功能 (上、下、左、右方键控制蛇的动作)
蛇撞墙死亡
蛇撞自身死亡
计算得分
蛇身加速、减速
暂停游戏

3.技术要点

C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。

4.WIN32 API

WIN32 API是windows操作系统最基本的API之一,它定义了windows操作系统的各种操作的函数和数据结构,WIN32 API也就是Windows 32位平台的应用程序编程接口。

4.1控制台程序

我们平时运行代码的时候那个黑色框程序其实就是控制台程序

然后可以使用cmd命令来控制黑色框的长度和宽度:设置控制台窗口的大小:200行,50列

mode con cols=200 lines=50

参考:mode | Microsoft Learn

然后通过命令来修改控制台名字

title 贪吃蛇

效果:

参考:mode | Microsoft Learn

通过c语言的system函数来实现:

#include <stdio.h>
int main()
{//设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,50⾏,200列system("mode con cols=200 lines=50");//设置cmd窗⼝名称system("title 贪吃蛇"); return 0;
}
4.2控制屏幕上的坐标COORD

参考:COORD 结构 - Windows Console | Microsoft Learn

COORD是windowsAPI中定义的一个结构体,它可以表示字符在屏幕上的坐标,最左上角的位置坐标是(0,0)。

COORD类型的声明:
typedef struct _COORD {SHORT X;SHORT Y;
} COORD, *PCOORD;

给坐标赋值:

COORD pos = { 10, 15 };
4.3.GetStdHandle(简单了解会用即可)

相关了解:GetStdHandle 函数 - Windows Console | Microsoft Learn

GetStdHandle是⼀个Windows API函数。它用于从⼀个特定的标准设备(标准输入、标准输出或标准错误)中取得⼀个句柄(用来标识不同设备的数值),使用这个句柄可以操作设备。
 HANDLE GetStdHandle(DWORD nStdHandle);

例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

HANDLE是一种类型;

4.4.GetConsoleCursorInfo(会用即可)
相关了解: GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

例:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
4.5.CONSOLE_CURSOR_INFO(简单了解会用即可)

这是一个结构体,包含了控制台的光标的相关信息:

typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

其中

dwSize,由光标填充的字符单元格的百分比。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的水平线条。
bVisible,游标的可见性。 如果光标可见,则此成员为 TRUE。
例:
CursorInfo.bVisible = false; //隐藏控制台光标
4.6.SetConsoleCursorInfo(简单了解会用即可)

相关了解:SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

SetConsoleCursorInfo可以 设置指定控制台屏幕缓冲区的光标的大和可见性
例:
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
4.7.SetConsoleCursorPosition(简单了解会用即可)

相关了解:SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。
例:
COORD pos = { 10, 5};HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);

写贪吃蛇时为了方便可以将上面的初始化信息封装成一个函数

例:

//设置光标的坐标
void SetPos(short x, short y)
{//取句柄HANDLE hOutput = NULL;hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//移动光标位置COORD pos = { x, y };SetConsoleCursorPosition(hOutput, pos);
}
4.8.GetAsyncKeyState(简单了解会用即可)

相关了解:getAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn

键盘中每个按键都有与之对应的虚拟值。

获取按键情况,GetAsyncKeyState的函数原型如下:
SHORT GetAsyncKeyState(int vKey
);
GetAsyncKeyState 的返回值是short类型,在上⼀次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中,最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。如果要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.
我们可以定义宏:
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

虚拟键:虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn

5.地图

游戏地图效果:

其中有一些宽字符想要打印还要再作一些处理

5.1<locale.h>本地化(简单了解会用即可)
<locale.h>提供的函数用于控制C标准库中对于不同的地区会产生不⼀样行为的部分。
在标准中,依赖地区的部分有以下几项:
数字量的格式
货币量的格式
字符集
日期和时间的表示形式
这里我们主要是获得字符的修改。
5.2.类项

通过修改地区,程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部分,其中⼀部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下面的⼀个宏,指定⼀个类项:
LC_COLLATE:影响字符串比较函数 strcoll() strxfrm()
LC_CTYPE:影响字符处理函数的行为。
LC_MONETARY:影响货币格式。
LC_NUMERIC:影响 printf() 的数字格式。
LC_TIME:影响时间格式 strftime() wcsftime()
LC_ALL - 针对所有类项修改,将以上所有类别设置为给定的语言环境。
相关了解: setlocale,_wsetlocale | Microsoft Learn
5.3setlocale函数
char* setlocale (int category, const char* locale);
setlocale 函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。
setlocale 的第⼀个参数可以是前面说明的类项中的⼀个,那么每次只会影响⼀个类项,如果第⼀个参数是LC_ALL,就会影响所有的类项。
C标准给第二个参数仅定义了2种可能取值: "C" (正常模式)和 " " (本地模式)。
在任意程序执行开始,都会隐藏式执行调用:
setlocale(LC_ALL, "C");
当地区设置为"C"时,库函数按正常方式执行,小数点是⼀个点。
当程序运行起来后想改变地区,就只能显示调用setlocale函数。用" "作为第2个参数,调用setlocale 函数就可以切换到本地模式,这种模式下程序会适应本地环境。
比如:切换到我们的本地模式后就支宽字符(汉字)的输出等。
setlocale(LC_ALL, " ");//切换到本地环境
5.4.宽字符的打印
宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。前缀“L”在单引
号前面,表示宽字符,对应 wprintf() 的占位符为 %lc ;在双引号前,表示宽字符串,对应 wprintf() 的占位符为 %ls
例:
#include<locale.h>
int main() {setlocale(LC_ALL, "");wchar_t ch1 = L'●';wchar_t ch2 = L'晚';wchar_t ch3 = L'成';wchar_t ch4 = L'★';printf("%c%c\n", 'a', 'b');wprintf(L"%lc\n", ch1);wprintf(L"%lc\n", ch2);wprintf(L"%lc\n", ch3);wprintf(L"%lc\n", ch4);return 0;
}

输出结果:

这里看到一个汉字或者一个宽字符需要占两个字符的位置,所以我们打印地图和对蛇,食物的坐标进行处理时一定要注意。

5.5.地图坐标

我们要设置一个40行,54列的地图:

5.6蛇身和食物
初始化状态,假设蛇是连续5个节点。
注意:蛇的每个节点的x坐标必须是2个倍数,否则可能会出现蛇的⼀个节点有⼀半出现在墙体中,
另外一半在墙外的现象,坐标不好对齐。
关于食物,就是在墙体内随机生成⼀个坐标(x坐标必须是2的倍数),坐标不能和蛇的身体重合,然后打印★。
效果如上图:
5.7数据结构设计

蛇每吃一个食物,蛇身就会变长一节,因此我们可以用链表来存蛇的信息,每一个结点只要记录好蛇的坐标就行,食物同样也是用这个链表来存。

typedef struct SnakeNode{int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;

然后维护蛇还要一个结构体:

typedef struct Snake
{pSnakeNode _pSnake;//维护整条蛇的指针pSnakeNode _pFood;//维护⻝物的指针enum DIRECTION _Dir;//蛇头的⽅向,默认是向右enum GAME_STATUS _Status;//游戏状态int _Socre;//游戏当前获得分数int _foodWeight;//默认每个⻝物10分int _SleepTime;//每⾛⼀步休眠时间
}Snake, * pSnake;

蛇的方向可以用枚举:

//⽅向
enum DIRECTION
{UP = 1,DOWN,LEFT,RIGHT
};

游戏的状态:

//游戏状态
enum GAME_STATUS
{OK,//正常运⾏KILL_BY_WALL,//撞墙KILL_BY_SELF,//咬到⾃⼰END_NOMAL//正常结束
};

6.游戏流程

7.游戏参考代码

c语言: 储存c代码 - Gitee.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/321881.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tf2使用savemodel保存之后转化为onnx适合进行om模型部署

tf2使用savemodel保存之后转化为onnx适合进行om模型部署 tf保存为kears框架h5文件将h5转化为savemodel格式&#xff0c;方便部署查看模型架构将savemodel转化为onnx格式使用netrononnx模型细微处理代码转化为om以及推理代码&#xff0c;要么使用midstudio tf保存为kears框架h5文…

MFC 列表控件修改实例(源码下载)

1、本程序基于前期我的博客文章《MFC下拉菜单打钩图标存取实例&#xff08;源码下载&#xff09;》 2、程序功能选中列表控件某一项&#xff0c;修改这一项的按钮由禁止变为可用&#xff0c;双击这个按钮弹出对话框可对这一项的记录数据进行修改&#xff0c;点击确定保存修改数…

运维自动化工具:Ansible 概念与模块详解

目录 前言 一、运维自动化工具有哪些 二、Ansible 概述 1、Ansible 概念 2、Ansible 特点 3、Ansible 工作流程 4、Ansible 架构 4.1 Ansible 组成 4.2 Ansible 命令执行来源 5、Ansible 的优缺点 三、Ansible 安装部署 1、环境部署 2、管理节点安装 Ansible 3、…

解锁AI的神秘力量:LangChain4j带你步入智能化实践之门

关注微信公众号 “程序员小胖” 每日技术干货&#xff0c;第一时间送达&#xff01; 引言 在数字化转型的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正逐渐成为推动企业创新和增长的关键力量。然而&#xff0c;将AI技术融入到日常业务流程并非易事&#xff0c;它…

20230507,LIST容器

学了又忘学了又忘&#xff0c;明知道会忘又不想复习又还得学 LIST容器 1.1 基本概念 链表是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的&#xff1b;链表由一系列结点组成 结点&#xff1a;一个是存储数据元素的数据域&a…

Electron项目中将CommonJS改成使用ES 模块(ESM)语法preload.js加载报错

问题 将Electron项目原CommonJS语法改成使用ES 模块&#xff08;ESM&#xff09;语法&#xff0c;preload.js一直加载不到&#xff0c;报错如下&#xff1a; VM111 renderer_init:2 Unable to load preload script: D:\Vue\wnpm\electron\preload.js VM111 renderer_init:2 E…

NGINX App Protect现已支持NGINX开源版 全方位加强现代应用安全防护

近日&#xff0c;F5 NGINX 发布全新升级的NGINX App Protect 5.0版本&#xff0c;将先前专属于NGINX 商业版本NGINX Plus 的现代应用安全能力拓展至NGINX开源版中&#xff0c;为增强现代应用和API安全防护提供全方位支持。此次升级后&#xff0c;适用于云端及本地部署的NGINX A…

Dell EMC Storage Unity: Remove/Install Memory Module

SP A 一个内存故障 点击system view -> Enclosures->Top查看 再次查看Alert&#xff0c; 确认内存出现问题 进入Service &#xff0c; 将SP A置为service状态 移出SP A &#xff0c;进行内存更换 更换完内存后&#xff0c;将SP A插入设备&#xff0c;并进行线缆连接 进入…

Maven+Junit5 + Allure +Jenkins 搭建 UI 自动化测试实战

文章目录 效果展示Junit 5Junit 5 介绍Junit 5 与 Junit 4 对比PageFactory 模式编写自动化代码公共方法提取测试用例参数化Jenkins 搭建及配置参数化执行生成 Allure 报告Maven 常用命令介绍POM 文件效果展示 本 chat 介绍 UI 自动化测试框架的搭建: 运用 page factory 模式…

AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

教育界最厉害的三个名人颜廷利:处处物尽其用, 时时人尽其才

颜廷利教授在他的著作《升命学说》中提出了“净化论”&#xff0c;这一理论**强调了个人内在心灵的宁静与纯洁对于实现更高层次人生价值的重要性**。 “净化论”是中国最受欢迎的著名起名字大师颜廷利教授关于如何提升个人命运和推动社会发展的哲学思考的一部分。他在书中提出&…

Baidu Comate:智能编码助手,助力编程效率飞跃

文章目录 Baidu Comate智能助手简介安装Baidu ComateBaidu Comate主要功能代码智能补全编程知识问答官方插件函数注释行间注释生成单测代码解释调优建议函数拆分清空对话框help AutoWork工具箱 总结 Baidu Comate智能助手简介 Baidu Comate&#xff0c;Coding Mate Powered by …

Express路由

什么是路由 官方定义&#xff1a;路由确定了应用程序如何响应客户端对特定端点的请求。 路由的使用 一个路由的组成有 请求方法、路径 和 回调函数 组成。 Express中提供了一些列方法&#xff0c;可以很方便的使用路由&#xff0c;使用格式如下&#xff1a; app.<metho…

【编程题-错题集】非对称之美(找规律 / 贪心)

牛客对应题目链接&#xff1a;非对称之美 (nowcoder.com) 一、分析题目 找规律&#xff1a; 判断是否全都是相同字符。判断本身是否是回文。 如果这个字符串每个字符相同&#xff0c;不存在非回文子串&#xff0c;直接返回 0。如果这个字符串不是回文&#xff0c;输出字符串长度…

一、RocketMQ基本概述与部署

RocketMQ基本概述与安装 一、概述1.MQ概述1.1 用途1.2 常见MQ产品1.3 MQ常用的协议 2.RocketMQ概述2.1 发展历程 二、相关概念1.基本概念1.1 消息&#xff08;Message&#xff09;1.2 主题&#xff08;Topic&#xff09;1.3 标签&#xff08;Tag&#xff09;1.4 队列&#xff0…

STC15W1K16S和VC6.0串口通讯收发测试实例

/********************************************* STC USB 串口板 2014 4 7 20:12 发送接收数据 使用STC串口调试助手通讯正常&#xff0c;L161 **********************************************/ #include "reg51.h" #include "intrins.h" #define…

sourceTree push失败

新电脑选择commit and push&#xff0c;报错了&#xff0c;不过commit成功&#xff0c;只不过push失败了。 原因是这个&#xff0c;PuTTYs cache and carry on connecting. 这里的ssh选择的是 PuTTY/Plink&#xff0c;本地没有这个ssh密钥&#xff0c;改换成openSSH&#xff…

[oeasy]python0015_键盘改造_将esc和capslock对调_hjkl_移动_双手正位

键盘改造 &#x1f94b; 回忆上次内容 上次练习了复制粘贴 按键 作用 <kbd>y</kbd><kbd>y</kbd> 复制光标行代码 到剪贴板 <kbd>p</kbd> 粘贴剪贴板中的内容 <kbd>i</kbd> 切换到 插入模式 <kbd>h</kbd>…

如何理解GTX接收通道相关模块?(高速收发器三)

前文讲解了GTX的时钟及发送通道相关内容&#xff0c;本文讲解GTX接收通道的一些功能及其IP配置&#xff0c;接收往往比发送设计更难&#xff0c;与调制解调&#xff0c;加密解密其实相差不大&#xff0c;后者难度都比前者高出很多。GTX的接收通道的功能相比发送通道更加重要&am…

【Linux】进程的隔离和控制:namespace 隔离、cgroup 控制

文章目录 五、namespace 隔离dd -- 读取、转换并输出数据mkfs -- 格式化文件系统df -- 显示文件系统磁盘使用情况mount -- 加载文件系统到指定的加载点unshare -- 创建子进程&#xff0c;同时与父程序不共享namespace一个 demo 六、cgroup(Control Group) 相关命令pidstat -- 监…