贪吃蛇小游戏的代码实现之知识点铺垫篇

2023-12-26 07:44

本文主要是介绍贪吃蛇小游戏的代码实现之知识点铺垫篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天给大家介绍一个很经典的小游戏,它和扫雷在经典小游戏这方面可以说是旗鼓相当,它的名字就是贪吃蛇。贪吃蛇游戏最初为单机模式,后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。该游戏具体玩法是:用游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。由于该游戏在实现过程中需要涉及一些未学习(我本身也比较陌生)的知识点且篇幅较大,所以在这里单独出一篇文章作为铺垫篇。

目录

1.涉及知识点总结

2.知识点讲解(我个人已学习)

3.知识点补充说明(我个人也比较陌生)

4.Win32API介绍

4.1Win32API

4.2控制台程序

4.3控制台所需掌握的指令 

4.4GetStdHandle 函数 - Windows Console | Microsoft Learn

4.5GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

4.6SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

4.7SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

4.8GetAsyncKeyState function (winuser.h) - Win32 apps | Microsoft Learn


1.涉及知识点总结

C语言、数据结构(链表)、枚举、结构体、动态内存管理、预处理指令、win32API

2.知识点讲解(我个人已学习)

因为我习惯以博客作为笔记进行学习,所以对于C语言中大部分常用知识点就进行了梳理。(自认为比较清晰,而且有一定自己的理解)那么,大家对于C语言中比较常用的知识点都有些陌生的,可以看一下我下面的这个专栏。

http://t.csdnimg.cn/gCvpYicon-default.png?t=N7T8http://t.csdnimg.cn/gCvpY专栏中具体讲解了C语言、枚举、结构体、动态内存管理等内容,大家可以根据个人需要酌情进行阅读。

3.知识点补充说明(我个人也比较陌生)

如果有朋友留意的话,会发现在上面的专栏中有三部分内容的缺失:①数据结构、②预处理指令、③win32API。解释一下,预处理指令,因为当前无法讲解比较深入,或者说当前也没有用太深的需求,大家自行简单了解一下即可;数据结构则因为首先使用也比较基础不用着重讲,并且下阶段准备出专栏讲解数据结构,所以也暂且不讲;那么今天就当仁不让地主讲win32API。

4.Win32API介绍
4.1Win32API

Windows这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外,它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程式达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application),所以便称之为ApplicationProgrammingInterface,简称API函数。WIN32API也就是MicrosoftWindows 32位平台的应用程序编程接口。

4.2控制台程序

什么是控制台呢?就是我们运行过无数次跳出来的黑色框框。

控制台窗口的坐标如下所示,横向的是X轴,从左向右依次增长,纵向是Y轴,从上到下依次增长。

在游戏地图上,我们打印墙体使用宽字符:□,打印蛇使用宽字符●,打印食物使用宽字符★

普通的字符是占一个字节的,这类宽字符是占用2个字节。

这里再简单的讲一下C语言的国际化特性相关的知识,过去C语言并不适合非英语国家(地区)使用。 C语言最初假定字符都是英语地区自己的。但是这些假定并不是在世界的任何地方都适用。 C语言字符默认是采用ASCII编码的,ASCII字符集采用的是单字节编码,且只使用了单字节中的低7 位,最高位是没有使用的,可表示为0xxxxxxxx;可以看到,ASCII字符集共包含128个字符,在英语国家中,128个字符是基本够用的,但是,在其他国家语言中,比如,在法语中,字母上方有注音符号,它就无法用ASCII码表示。于是,一些欧洲国家就决定,利用字节中闲置的最高位编入新的符号。比如,法语中的é的编码为130(⼆进制10000010)。这样一来,这些欧洲国家使用的编码体系,可以表示最多256个符号。但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不⼀样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel( ),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0--127表示的符号是一样的,不一样的只是128--255的这一段。 ⾄于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表表256种符号, 肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。 后来为了使C语言适应国家化,C语言的标准中不断加入了国际化的支持。比如:加入和宽字符的类型 wchar_t 和宽字符的输入和输出函数,加入和头文件,其中提供了允许程序员针对特定地区(通常是国家或者说某种特定语言的地理区域)调整程序行为的函数。

提供的函数用于控制C标准库中对于不同的地区会产生不一样行为的部分。 在标准可以中,依赖地区的部分有以下几项:

• 数字量的格式

• 货币量的格式

• 字符集

• 日期和时间的表示形示

通过修改地区,程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部分,其中一部分可能是我们不希望修改的。所以C语言支持针对不同的类项进行修改,下面的一个宏, 指定一个类项:

• LC_COLLATE

• LC_CTYPE

• LC_MONETARY

• LC_NUMERIC

• LC_TIME

• LC_ALL-针对所有类项修改

4.3控制台所需掌握的指令 

对于控制台,C语言使用system(“ ”)来调用windows指令来执行控制台的指令(其实Windows控制台和LINUX差不多,其基本的原理是相同的)在这里,我们需要掌握的几条指令如下:
①system(“mode con cols=x lines=y”):对控制台的大小进行控制

 mode con cols=100 lines=30


②system("title 对应名字“):用来改变控制台的名字

title 贪吃蛇


③system(“pause”):负责暂停程序,并打印出按任意键继续,可控制输出坐标

pause


④system(“cls”):刷新界面,然后执行接下来的程序

cls


注意:对于双引号里面的命令,其实就是对应着windows控制台的操作指令,只不过C语言用这种方式命令控制台执行,当然上面的代码区域是system括号中双引号内的内容,谁要是不加最基本的system(""),我能笑到2024年?😀

4.4GetStdHandle 函数 - Windows Console | Microsoft Learn

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

 HANDLE GetStdHandle(DWORD nStdHandle);

实例代码如下:

HANDLE hOutput = NULL;//
获取标准输出的句柄
(
⽤来标识不同设备的数值
) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
4.5GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息

BOOL WINAPI GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);

实例代码如下:

 HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值) hOutput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

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.6SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

设置指定控制台屏幕缓冲区的光标的大小和可见性。 

BOOL WINAPI SetConsoleCursorInfo(HANDLE  hConsoleOutput,const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo);

实例代码如下:
 

 HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//隐藏光标操作CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
4.7SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。 

BOOL WINAPI SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD  pos);

 实例代码如下:

COORD pos = { 10, 5};HANDLE hOutput = NULL;//
获取标准输出的句柄
(
⽤来标识不同设备的数值
) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//
设置标准输出上光标的位置为
pos 
SetConsoleCursorPosition(hOutput, pos);

SetPos:封装一个设置光标位置的函数

 //设置光标的坐标void SetPos(short x, short y){COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值) hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为pos SetConsoleCursorPosition(hOutput, pos);}
4.8GetAsyncKeyState function (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 )

这篇关于贪吃蛇小游戏的代码实现之知识点铺垫篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538599

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景