C语言小游戏--贪吃蛇实现

1.游戏实现背景

贪吃蛇小游戏在很早以前就已经存在,我们应该也玩过贪吃蛇这个游戏,这一讲实现的贪吃蛇小游戏是基于C语言,以及链表来实现的,目的在于培养代码思维,对前面的知识做出总结

2.Win32 API介绍

本次贪吃蛇的实现需要用到很多关于Win32 API的知识,我们现在来了解一下:

2.1什么是Win32 API

Win32 API是一组用于Windows操作系统的应用程序编程接口,它提供了一组函数,允许程序员访问操作系统的服务(Windows这个多作业系统除了协调程序的运行、分配内存、管理资源之外,同时是一个很大的服务中心),如 文件管理、内存管理、进程控制、图形和声音处理等

2.2控制台程序(Console)

平时我们运行起来的黑框就是控制台程序
我们可以使用cmd命令来改变控制台窗口的长宽:长为 30、宽为30

//lines:行  cols:列
mode con cols=30 lines=30

我们还可以改变控制台窗口的名称:

title 测试API程序

这些能在控制台窗口执行的命令,也能够调用C语言system函数来执行:

//控制台程序
#include <stdlib.h>
int main()
{
   
	system("mode con cols=30 lines=30");//改变运行窗口的大小
	system("title 测试API程序");//改变运行窗口的名字

	return 0;
}

最终效果:
在这里插入图片描述
但是我们会发现:我们设的长和宽分明是相等的,但是为什么控制台窗口的大小不是一个正方形呢?我们来看:

2.3控制台屏幕的坐标COORD

COORD是Windows API中定义的一个结构体,表示一个字符在屏幕缓冲区的一个坐标,坐标的分布如下:
在这里插入图片描述
COORD结构体的定义为:

//COORD结构体定义了x和y坐标
typedef struct _COORD {
   
	SHORT X;
	SHORT Y;
} COORD, * PCOORD;

我们使用这一个结构体也较为简单,假设我们要给一个坐标赋值:

COORD pos = {
   10, 20};

2.4GetStdHandle

GetStdHandle是一个Windows API函数,用于从一个标准设备(标准输入设备、标准输出设备)中获得一个句柄(我们可以将句柄通俗地理解成:操纵操作系统的把柄),有了这个句柄,我们就可以来操纵操作系统

2.4.1函数语法

既然为函数,就应该存在语法,它的函数定义为:

HANDLE WINAPI GetStdHandle(
  _In_ DWORD nStdHandle
);

该函数只有一个参数nStdHandle,对于该参数的介绍为:
在这里插入图片描述
如果函数成功,那么函数将会返回指定设备的句柄

2.4.2函数的使用

#include <windows.h>
int main()
{
   
	//函数返回的是一个句柄,那么我们就可以使用一个句柄来接受,我们先创建一个句柄变量
	HANDLE hOutput = NULL;

	//获取标准输出的句柄
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	return 0;
}

2.5GetConsoleCursorInfo

2.5.1函数语法

BOOL WINAPI GetConsoleCursorInfo(
	_In_  HANDLE               hConsoleOutput,
	_Out_ PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);

函数有两个参数:
1.hConsoleOutput:这个是控制台屏幕缓冲区的句柄
2.lpConsoleCursorInfo:它是指向CONSOLE_CURSOR_INFO结构的指针,该结构可以接受有关主机光标的信息
如果该函数成功,会返回非零值,函数失败,会返回零

2.5.2函数的使用

int main()
{
   
	//获得一个句柄
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	
	//创建一个光标信息的变量
	CONSOLE_CURSOR_INFO Cursorinfo;
	//使用含税获取光标信息
	GetConsoleCursorInfo(hOutput, &Cursorinfo);

	return 0;
}

2.6CONSOLE_CURSOR_INFO

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

2.6.1结构体结构

typedef struct _CONSOLE_CURSOR_INFO {
   
	DWORD dwSize;
	BOOL  bVisible;
} CONSOLE_CURSOR_INFO, * PCONSOLE_CURSOR_INFO;
结构体中包含两个参数:
1.dwSize:表示的是游标填充字符单元的百分比,该值介于1-100之间
2.bVisible:表示游标的可见性,如果游标可见,那么此成员为True

2.6.2结构体的使用

int main()
{
   
	//获得一个句柄
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	
	//创建一个光标信息的变量
	CONSOLE_CURSOR_INFO Cursorinfo;
	//使用含税获取光标信息
	GetConsoleCursorInfo(hOutput, &Cursorinfo);

	//结构体的使用:打印一下此时控制台光标占填充字符单元的百分比
	printf("%d", Cursorinfo.dwSize);//25,也就是说此时光标占一个字符单元的百分之25
	return 0;
}

在这里插入图片描述

2.7SetConsoleCursorInfo

2.7.1函数语法

BOOL WINAPI SetConsoleCursorInfo(
  _In_       HANDLE              hConsoleOutput,
  _In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);
该函数有两个参数:
1.hConsoleOutput:指向控制台屏幕缓冲区的句柄
2.lpConsoleCursorInfo:指向CONSOLE_CURSOR_INFO结构体的指针
该函数如果成功,返回非零值,失败返回零

2.7.2函数的使用

#include <stdbool.h>
int main()
{
   
	//获得一个句柄
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//创建一个光标信息的变量
	CONSOLE_CURSOR_INFO Cursorinfo;
	//使用含税获取光标信息
	GetConsoleCursorInfo(hOutput, &Cursorinfo);

	//函数的使用:
	//我们可以根据我们不同的需求对光标进行修改
	//1.修改光标大小
	Cursorinfo.dwSize = 50;//直接修改结构体中的参数然后Set就好了
	SetConsoleCursorInfo(hOutput, &Cursorinfo);
	//2.隐藏光标
	Cursorinfo.bVisible = false;
	SetConsoleCursorInfo(hOutput, &Cursorinfo);
	return 0;
}

2.8SetConsoleCursorPosition

这是一个设置光标位置的函数

2.8.1函数语法

BOOL WINAPI SetConsoleCursorPosition(
	_In_ HANDLE hConsoleOutput,
	_In_ COORD  dwCursorPosition
);
该函数有两个参数:
1.hConsoleOutput:控制台屏幕缓冲区的句柄
2.dwCursorPosition:指定新光标位置的COORD结构,坐标为屏幕缓冲区字符单元的列和行,坐标必须位于控制台屏幕缓冲区的边界之内
如果函数成功,则返回非零值,函数失败,返回零

2.8.2函数的使用

int main()
{
   
	//定义一个光标结构体,标志着需要将光标定位的位置
	COORD pos = {
    15, 30 };

	//获得句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//设置光标位置
	SetConsoleCursorPosition(hOutput, pos);
	return 0;
}

此时光标位置就被改变了:
在这里插入图片描述

2.8.3设置一个光标位置的函数

我们在设计贪吃蛇小游戏的过程中,要在不同位置放置食物、提示信息等,所以我们可以封装一个设置光标位置的函数,方便后续使用

//封装一个设置光标位置的函数
void SetPos(short x, short y)
{
   
	//函数构造比较简单,只需要使用Set函数即可
	//1.光标位置结构体
	COORD pos = {
    x, y };

	//2.获得句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//3.设置光标信息
	SetConsoleCursorPosition(hOutput, pos);
}

2.9GetAsyncKeyState

这个函数是用来获取按键情况的函数,这个在游戏中作用很大

2.9.1函数语法

SHORT GetAsyncKeyState(
  [in] int vKey
);
函数只有一个参数:
vKey:表示虚拟按键代码,每一个按键都有一个对应的值,将值传入就可以判断该按键是否被按着或者被按过
函数的返回值为short类型,在上一次调用该函数后,如果返回的16位的short数据中,最高位为1,说明状态是按下的,如果最低位为1,说明该按键被按过

链接: 虚拟键代码值
我们可以通过上面的一个链接来看按键的代码值为多少

2.9.2函数的使用

//我们可以写一个宏,通过使用宏我们可以更高效地判断按键的状态
#define KEY_STATE(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1: 0 )//如果返回值的最低位为1,表示该按键被按过

//检测数字键的实现
int main()
{
   
	while(1)
	{
   
		if (KEY_STATE(0x30))//0x30表示按键0
		{
   
			printf("0\n");
		}
		else if (KEY_STATE(0x31))
		{
   
			printf("1\n");</
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值