贪吃蛇小游戏(c语言)

简介: 贪吃蛇小游戏(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 贪吃蛇

效果:

b454178bcc6f4a2784354243471e8f55.png

参考: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)。

8bd86db38b7a4ce8859544121761a821.png

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);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(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.地图

游戏地图效果:

b0bccb56a2cd402193870570d755e478.png

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


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;
}


输出结果:

e40086f693734e5b9c737cbff8b6806e.png

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


5.5.地图坐标

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

87a4870c5f8e436a9b65671c42b53055.png


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.游戏流程

2a0c7026f39f449eb9979b3e085a7881.png


7.游戏参考代码

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

目录
相关文章
|
9天前
|
C语言
C语言小插曲——对图形库的初步探索(消除小球小游戏)
C语言小插曲——对图形库的初步探索(消除小球小游戏)
8 0
|
18天前
|
C语言 C++
C语言项目(1)----扫雷小游戏的实现
C语言项目(1)----扫雷小游戏的实现
21 0
|
23天前
|
C语言
【C语言入门小游戏】扫雷
【C语言入门小游戏】扫雷
21 1
|
23天前
|
编译器 C语言
【C语言入门小游戏】三子棋
【C语言入门小游戏】三子棋
24 0
【C语言入门小游戏】三子棋
TU^
|
23天前
|
存储 程序员 定位技术
C语言实现贪吃蛇
贪吃蛇游戏介绍
TU^
28 0
|
24天前
|
C语言
C语言简单小游戏——扫雷
C语言简单小游戏——扫雷
|
24天前
|
C语言
史上最简单的C语言猜数字小游戏(1—100随机数)
史上最简单的C语言猜数字小游戏(1—100随机数)
|
25天前
c语言学完数组就能做的小游戏--扫雷
c语言学完数组就能做的小游戏--扫雷
|
25天前
c语言学完数组就可以完成的小游戏--三子棋
c语言学完数组就可以完成的小游戏--三子棋
|
2天前
|
算法 Unix Linux
C语言随机数的产生(rand、srand、time函数细节讲解)
C语言随机数的产生(rand、srand、time函数细节讲解)

相关实验场景

更多