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

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

目录

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轴,从上到下依次增长。

贪吃蛇小游戏的代码实现之知识点铺垫篇_第1张图片

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

普通的字符是占一个字节的,这类宽字符是占用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 )

你可能感兴趣的:(有趣的代码,c语言,数据结构,蓝桥杯,青少年编程,算法)