贪吃蛇(C语言实现)

本文详细讲解了如何用C语言实现贪吃蛇小游戏。介绍了Win32API相关知识,用于控制界面和光标;讲解了<locale.h>头文件,以支持国际化。还阐述了预处理、游戏函数、结构体和枚举的使用,以及游戏开始、运行和结束的具体实现,最后给出代码模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最终的代码在最后,如果只是想要玩贪食蛇的,可以直接滑到最后直接CV。

本章我们来讲解如何用C语言实现贪吃蛇小游戏。

这篇文章很长,而且有难度,很考察你的思维能力与代码能力,希望能帮助到你,如果你无法理解,也可以找我问,我很乐意解答

话不多说,我们直接开始

目录

演示效果:

Win32API:

1.控制台程序:

2.控制台屏幕上的坐标COORD:

3.GetStdHandle

4.GetConsoleCursorInfo

ⅠCONSOLE_CURSOR_INFO

5.SetConsoleCursorInfo

6.SetConsoleCursorPosition

7.GetAsyncKeyState

讲解

1.locale的本地化

2.类型

3. setlocale函数

4.宽字符的打印

预处理

游戏函数

结构体和枚举的使用

游戏实现

1.GameStart

先设置窗口大小,光标隐藏

  打印游戏界面,功能介绍

绘制地图

创建食物

创建蛇和设置游戏的相关信息

2.GameRun

打印帮助信息

蛇的运动

蛇的加速与减速

3.GameEnd

总结:

snake.h:函数的声明以及头文件预处理

Snake.c:函数的具体实现

test.c:测试逻辑(Main函数在这里)


先看演示效果

演示效果:

以上只是模板,我们要做的是根据模板写出源代码

要想完成贪吃蛇项目,我们需要掌握C语⾔函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32API等知识,其他的不必多说,我们需要单独了解一下Win32API的知识

Win32API:

首先,我们在贪吃蛇项目中使用API是为了控制界面大小光标位置的,这两个作用至关重要。

Windows这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外,它同时也是⼀个很⼤ 的服务中⼼,调⽤这个服务中⼼的各种服务(每⼀种服务就是⼀个函数),可以帮应⽤程序达到开启 视窗、描绘图形、使⽤周边设备等⽬的,由于这些函数服务的对象是应⽤程序(Application),所以便 称之为Application Programming Interface,简称API函数。WIN32 API也就是Microsoft Windows 32位平台的应⽤程序编程接⼝。

简单来说API就是一个大的函数集合,我们要使用其中的某些函数来实现我们的目的

1.控制台程序:

控制台程序即我们平常使用的黑框程序,我们可以用CMD指令来控制控制台窗口的大小,如设置长宽,即

mode con cols=100 lines=30

即用mode指令,如有兴趣可以了解一下mode指令mode

我们不仅可以通过cmd指令控制窗口大小,还可以对控制台进行命名,即

title 贪吃蛇

效果如图所示

而这些命令,都可以在C语言中利用system函数进行调用

#include <stdio.h>
int main()
{
 //设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列 
 system("mode con cols=100 lines=30");
 //设置cmd窗⼝名称 
 system("title 贪吃蛇"); 
 return 0;
}

2.控制台屏幕上的坐标COORD:

COORD是WindowsAPI中定义的⼀个结构体,表⽰⼀个字符在控制台屏幕幕缓冲区上的坐标,坐标系 (0,0)的原点位于缓冲区的顶部左侧单元格。

COORD结构体包含X,Y坐标

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

而X,Y的相对位置如图所示

我们可以给坐标赋值

COORD pos = { 10, 15 };

3.GetStdHandle

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

HANDLE GetStdHandle(DWORD nStdHandle); 
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

使用方法和使用实例如上所示,可见HANDLE是一个类型,其实就是void*类型,所以说我们创建变量初始化时,要置为NULL;

4.GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标⼤⼩和可⻅性的信息

用来获得控制台的光标信息

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

这个结构体,包含有关控制台光标的信息

转到定义我们可以看到两个变量

其中dwSize是光标的宽度,而bVisible是光标的可见

  • dwSize,由光标填充的字符单元格的百分⽐。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的⽔平线条。
  • bVisible,游标的可⻅性。 如果光标可⻅,则此成员为 TRUE。

而作为游戏,我们肯定不希望光标一直在频闪,这样会影响我们的游戏体验,所以我们要将bVisible设置为FALSE,即隐藏光标

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

5.SetConsoleCursorInfo

设置指定控制台屏幕缓冲区的光标的⼤⼩和可⻅性。

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);//设置控制台光标状态

从代码中我们可以看到我们要先通过函数获取控制台的地址,再修改控制台光标的信息,最后再利用函数设置控制台的状态。

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

7.GetAsyncKeyState

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

SHORT GetAsyncKeyState(
int vKey
);

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。

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

通过这个函数,在我们控制贪吃蛇进行前后左右行走时,才能及时的调整方向,也是一个重要的函数。

以上就是贪吃蛇游戏所需要用到的Win32API的知识,有点抽象,需要慢慢去理解,也可以查找资料去理解。

讲解<locale.h>

这⾥再简单的讲⼀下C语⾔的国际化特性相关的知识,过去C语⾔并不适合⾮英语国家(地区)使⽤。
C语⾔最初假定字符都是单字节的。但是这些假定并不是在世界的任何地⽅都适⽤。

C语⾔字符默认是采⽤ASCII编码的,ASCII字符集采⽤的是单字节编码,且只使⽤了单字节中的低7
位,最⾼位是没有使⽤的,可表⽰为0xxxxxxxx;可以看到,ASCII字符集共包含128个字符,在英语
国家中,128个字符是基本够⽤的,但是,在其他国家语⾔中,⽐如,在法语中,字⺟上⽅有注⾳符
号,它就⽆法⽤ ASCII 码表⽰。于是,⼀些欧洲国家就决定,利⽤字节中闲置的最⾼位编⼊新的符
号。⽐如,法语中的é的编码为130(⼆进制10000010)。这样⼀来,这些欧洲国家使⽤的编码体
系,可以表⽰最多256个符号。但是,这⾥⼜出现了新的问题。不同的国家有不同的字⺟,因此,哪
怕它们都使⽤256个符号的编码⽅式,代表的字⺟却不⼀样。⽐如,130在法语编码中代表了é,在希
伯来语编码中却代表了字⺟Gimel (?),在俄语编码中⼜会代表另⼀个符号。但是不管怎样,所有这
些编码⽅式中,0--127表⽰的符号是⼀样的,不⼀样的只是128--255的这⼀段。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值