手把手教你实现贪吃蛇(上)

简介: 手把手教你实现贪吃蛇(上)

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:实现贪吃蛇

> 毒鸡汤:时间并不可真的帮我们去解决哪些问题,它只不过是会把原来怎么也想不通的问题,变得不再重要了。

> 望小伙伴们点赞👍收藏✨加关注哟💕💕

🌟前言

       作为零零后的我们想必贪吃蛇都玩过吧,博主记得当时还在小霸王里面玩的这款小游戏,十分怀念,记忆深刻,每次都是偷偷躲在被窝里面玩,为了防止别抓,基本上是躲在厕所里面玩,上个厕所上个十年,丑事不必再提。作为一个程序员捏,当然要简单的实现它啦,也是为曾经的自己画上一个圆满的句号吧。那咱们闲话少谈,直接手撕贪吃蛇。

⭐游戏背景

       我们采用的是VS2019编译环境,所以家人们准备好编译环境,当然咱们上手不能直接上代码,可能一开始上代码就是从入门到放弃,我懂大家的捏。咱们先介绍游戏,到时候反手就说,这个博主教我们怎么玩游戏,取关,必须取关,家人们不先知道怎么玩你怎么知道游戏的逻辑,给这些人拖出去斩了。

       不知道大家还记得在C语言中我们实现了两款游戏,一个是三子棋,另一个是扫雷,这些游戏和贪吃蛇是久负盛名的游戏,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的⾏列。



博主后面这些经典小游戏都会一一实现,刺激

游戏演示

看的是不是很神奇,一点也不神奇,不信你继续向下看。

贪吃蛇

⭐实现目标

使⽤C语⾔在Windows环境的控制台中模拟实现经典⼩游戏贪吃蛇
实现基本的功能:
• 贪吃蛇地图绘制
• 蛇吃⻝物的功能 (上、下、左、右⽅向键控制蛇的动作)
• 蛇撞墙死亡
• 蛇撞⾃⾝死亡
• 计算得分
• 蛇⾝加速、减速
• 暂停游戏

⭐技术要点

       C语⾔、数据结构(链表)、枚举、结构体、动态内存管理、预处理指令、win32 API(这个咱们后面讲解),这些基本上都学过哟,像链表不知道大家能不能手撕链表,不会的拖出去打30大板。

win32 API介绍

       使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 Microsoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。

       在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。

当然啦,咱们不用学习这里面全部知识,不然又要被黑子喷咯。

🌙Win32 API

       有一些函数,并不用于交互,比如管理当前系统正在运行的进程、硬件系统状态的监视等等……这些函数只有一套,但是可以被所有的Windows程序调用(只要这个程序的权限足够高),简而言之,API是为程序所共享的。

       为了达到所有程序能共享一套API的目的,Windows采用了“动态链接库”的办法。之所以叫“动态链接库”,是因为这样的函数库的调用方式是“随用随取”而不是像静态链接库那样“用不用都要带上”。

🌙控制台程序

       像我们运行一个代码,就有一个黑框框,没错它就是控制台程序,Win32 API我们是可以控制它滴,终于有人可以管得住它了,不然它还是一个野孩子。

我们可以使⽤cmd命令来设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列

1 mode con cols=100lines=30

也可以通过命令设置控制台窗⼝的名字:

1 title 贪吃蛇

耶嘿这孩子有名字咯。

🌙控制台屏幕上的坐标COORD

COORD 是Windows API中定义的⼀种结构,表示⼀个字符在控制台屏幕上的坐标

typedef struct _COORD {
  SHORT X;
  SHORT Y;
} COORD, * PCOORD;

给坐标赋值:

COORD pos = { 10, 15};

🌙GetStdHandle

       GetStdHandle是⼀个Windows API函数。它⽤于从⼀个特定的标准设备(标准输⼊、标准输出或标准错误)中取得⼀个句柄(⽤来标识不同设备的数值),使⽤这个句柄可以操作设备。简单的来讲就是可以用键盘控制控制台。

HANDLE GetStdHandle(DWORD nStdHandle);

HANDLE hOutput = NULL;

//获取标准输出的句柄(⽤来标识不同设备的数值)

hOutput = GetStdHandle(STD _OUTPUT_HANDLE);

🌙GetConsoleCursorInfo

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

BOOL WINAPI GetConsoleCursorInfo(

HANDLE hConsoleOutput,

PCONSOLE_CURSOR_INFO lpConsoleCursorInfo

);

实例:

HANDLE hOutput = NULL;

//获取标准输出的句柄(⽤来标识不同设备的数值)

hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

CONSOLE_CURSOR_INFO CursorInfo;

GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

🌙SetConsoleCursorInfo

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

BOOL WINAPI SetConsoleCursorInfo(

HANDLE hConsoleOutput,

constCONSOLE_CURSOR_INFO *lpConsoleCursorInfo

);

实例:

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

//影藏光标操作

CONSOLE_CURSOR_INFO CursorInfo;

GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

CursorInfo.bVisible = false; //隐藏控制台光标

SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

🌙SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在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(shortx, shorty)

{

COORD pos = { x, y };

HANDLE hOutput = NULL;

//获取标准输出的句柄(⽤来标识不同设备的数值)

hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

//设置标准输出上光标的位置为pos

SetConsoleCursorPosition(hOutput, pos);

}

🌙GetAsyncKeyState

获取按键情况,GetAsyncKeyState的函数原型如下:

SHORT GetAsyncKeyState( intvKey );

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。 是short类型,在上⼀次调⽤ GetAsyncKeyState 函数后,如果返回的16位的short数据中,最⾼位是1,说明按键的状态是按下,如果最⾼是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.

#defineKEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

贪吃蛇游戏设计与分析

这里我们得了解游戏的逻辑和框架,别慌,一步一步慢慢来!!!

🌙地图设计

咱们看看地图是如何设计的:

既然要设计地图,必然需要在VS2019下控制台的坐标问题。

       这里不得不讲一下控制台窗口的一些知识,如果想在控制台的窗⼝中指定位置输出信息,我们得知道该位置的坐标,所以首先介绍一下控制台窗⼝的坐标知识。控制台窗口的坐标如下所示,横向的是X轴,从左向右依次增长,纵向是Y轴,从上到下依次增长。

       在游戏地图上,我们打印墙体使⽤宽字符:□,打印蛇使用宽字符●,打印食物使用宽字符★普通的字符是占⼀个字节的,这类宽字符是占用2个字节。这里再简单的讲⼀下C语言的国际化特性相关的知识,过去C语言并不适合非英语国家(地区)使用。C语言最初假定字符都是但自己的。但是这些假定并不是在世界的任何地方都适用。

      后来为了使C语言适应国家化,C语言的标准中不断加入了国际化的支持。比如:加入和宽字符的类型 wchar_t 和宽字符的输⼊和输出函数,加入和头文件,其中提供了允许程序员针对特定 地区(通常是国家或者说某种特定语言的地理区域)调整程序行为的函数。

💫setlocale函数

char* setlocale (int category, const char* locale);

  1. setlocale 函数用于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。
  2. setlocale 的第一个参数可以是前面说明的类项中的一个,那么每次只会影响一个类项,如果第一个参数是LC_ALL,就会影响所有的类项。

C标准给第⼆个参数仅定义了2种可能取值:"C"和" "。在任意程序执⾏开始,都会隐藏式执⾏调⽤:

setlocale(LC_ALL, "C");

当地区设置为"C"时,库函数按正常方式执行,小数点是一个点。

当程序运行起来后想改变地区,就只能显⽰调⽤setlocale函数。用" "作为第2个参数,调setlocale

函数就可以切换到本地模式,这种模式下程序会适应本地环境。比如:切换到我们的本地模式后就支持宽字符(汉字)的输出等。

setlocale(LC_ALL, " ");//切换到本地环境

我们发现⼀个普通字符占⼀个字符的位置但是打印⼀个汉字字符,占⽤2个字符的位置,那么我们如果要在贪吃蛇中使⽤宽字符,就得处理好地图上坐标的计算。

💫地图坐标

       我们假设实现一个棋盘27行,58列的棋盘(行和列可以根据自己的情况修改),再围绕地图画出墙, 如下:

🌙蛇身和食物

       初始化状态,假设蛇的长度是5,蛇身的每个节点是●,在固定的一个坐标处,比如(24, 5)处开始出现蛇,连续5个节点。 注意:蛇的每个节点的x坐标必须是2个倍数,否则可能会出现蛇的⼀个节点有一半儿出现在墙体中,另外⼀般在墙外的现象,坐标不好对齐。 关于食物,就是在墙体内随机生成⼀个坐标(x坐标必须是2的倍数),坐标不能和蛇的身体重合,然后打印★。

🌙游戏流程设计


手把手教你实现贪吃蛇(下):https://developer.aliyun.com/article/1389419

目录
相关文章
|
编译器 C++
学习C++笔记378
C++ 预处理器
52 0
|
C++
学习C++笔记365
C++ 命名空间
57 0
|
存储 C++
学习C++笔记349
C++ 动态内存
51 0
|
C++
学习C++笔记308
C++ 多态
96 0
|
数据安全/隐私保护 C++
学习C++笔记281
C++ 类 & 对象
57 0
|
存储 C++
学习C++笔记266
C++ 数据结构
75 0
|
存储 C++
学习C++笔记260
C++ 数据结构
79 0
|
程序员 C++
学习C++笔记149
C++ 判断
69 0
|
程序员 C++
学习C++笔记142
C++ 运算符
69 0
|
C++
学习C++笔记141
C++ 循环
78 0