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

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

相关文章

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

C# 读写ini文件操作实现

《C#读写ini文件操作实现》本文主要介绍了C#读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、INI文件结构二、读取INI文件中的数据在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的