在我们学完了C语言的基础知识后,现在可以开始着手写一些简单的小游戏了 但是,要想通过键盘来控制人物的移动,我们该怎么办呢? 好像我们之前的学习中没有涉猎 所以在讲制作小游戏前,我们先要学习一个新的东西 它就是
Win 32 API
Win32 API(也称为 Windows API)是 Windows 应用的本机平台。 Windows系统除了协调应用程序的执行、分配内存、管理资源之外的同时也是一个很大的服务中心,这个服务中心提供了各种各样的服务(每一种服务就是一个函数),这些函数可以帮助应用程序开启视窗、描绘图形、使用周边设备等目的,因为这些函数服务的对象是应用程序(Application),因此被称为Application Programming Interface,简称API。此 API 最适合需要直接访问系统功能和硬件的桌面应用,可用于所有桌面应用,并且 32 位和 64 位 Windows 通常支持相同的功能。 WIN 32 API就是Microsoft Windows32平台的应用程序编程接口。
上面的介绍一句话就是: Win 32 APL 里面有很多函数,调用他们我们就可以实现游戏人物的移动等等东西 但注意: 调用时要加头文件
<Windows.h>
下面我们会讲解一部分关于Win 32 API的知识来帮助大家完成一些简易的小游戏
定义:在Windows中运行的黑框程序(命令提示符窗口)
这个就是我们电脑上的cmd,在搜索中搜cmd就可以出来了

我们可以用命令来进行窗口设置:
使用
mode con cols=100 lines=30命令设置窗口大小 (设置为100列×30行) 使用title 贪吃蛇命令设置窗口标题 这样就可以简易地创建一个游戏窗口啦
结果:

但是我们想要在VS2022编译器中用代码来操作控制台程序怎么办呢?
在我们的编译器中,可以用sysytem函数来操作控制台程序
头文件:
system函数头文件——<Windows.h>语法:
system(" 要实现的命令 ");
代码演示:(内有注释,不懂就看)
#include <stdio.h>
#include<Windows.h>
int main()
{
//设置窗口大小
system("mode con cols=100 lines=30");
//设置标题
system("title ZORE_C 的贪吃蛇");
//将程序进行暂停以免程序结束
//方便观察结果
system("pause");
return 0;
}运行结果:

下面我们就要在控制台程序上进行操作
功能: 获取标准设备的句柄(输入/输出/错误) 语法:
HANDLE WINAPI GetStdHandle( _In_ DWORD nStdHandle );
那什么是句柄呢? 句柄,可以理解为是一个指针,可以将标准设备的地址存起来 当下次你要操作这个标准设备时就调用该句柄 该句柄就可以找到标准设备并进行操作
其中,GetStdHandle函数参数为标准设备
参数_In_ DWORD nStdHandle的取值可为下列值之一:

返回值: HANDLE类型(本质是void指针)
下面我们就用函数来获取STD_OUTPUT_HANDLE标准输出的句柄
其中houtput就是句柄
代码演示:
//获取句柄
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
//获取STD_OUTPUT_HANDLE标准输出的句柄功能: 一个结构体,里面包含有关控制台游标的信息。 语法:
typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;BOOL bVisible;} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
那游标是什么呢? 在控制台上,可以看到一闪一闪的类似光标的东西,这就是游标
如下图:

dwSize由游标填充的字符单元格的百分比。 此值介于 1 和 100 之间 光标外观各不相同,范围从完全填充单元格到显示为单元格底部的水平线bVisible游标的可见性 如果游标可见,则此成员为TRUE。 如果游标不可见,则此成员为FALSE。
如下图:
在控制台上,默认游标的大小是25%(左边游标),而100%的游标(右边游标)
默认的可见性当然也是TRUE(可见)

功能: 检索有关指定控制台屏幕缓冲区的游标大小和可见性的信息 语法:
BOOL WINAPI GetConsoleCursorInfo(_In_ HANDLE hConsoleOutput,_Out_ PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);
_In_ HANDLE hConsoleOutput控制台屏幕缓冲区的句柄 (就是我们刚刚讲的句柄)_Out_ PCONSOLE_CURSOR_INFO lpConsoleCursorInfo指向 CONSOLE_CURSOR_INFO 结构体的指针 该结构体接收有关控制台游标的信息。 (就是我们刚刚讲的游标信息的结构体)
如果该函数成功,则返回值为非零值。 如果函数失败,则返回值为零。
现在,我们先创建一个
CONSOLE_CURSOR_INFO结构体变量用于存放默认的游标信息 然后,用GetConsoleCursorInfo函数检索有关指定控制台屏幕缓冲区的游标大小和可见性的信息 最后打印在屏幕上
代码演示:(内有注释,不懂就看)
#include <stdio.h>
#include<Windows.h>
int main()
{
//获取句柄
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
//获取STD_OUTPUT_HANDLE标准输出的句柄
//定义一个包含游标信息的结构体
CONSOLE_CURSOR_INFO cursor_info = { 0 };
//检索句柄指定控制台屏幕缓冲区的游标大小和可见性的信息
GetConsoleCursorInfo(houtput, &cursor_info);
//打印出大小的值
printf("游标大小为%d%%\n\n", cursor_info.dwSize);
//将程序进行暂停以免程序结束
//方便观察结果
system("pause");
return 0;
}运行结果:

可以看到,由于游标默认的值是25%,故打印出25
功能: 为指定的控制台屏幕缓冲区设置光标的大小和可见性。 语法:
BOOL WINAPI SetConsoleCursorInfo(_In_ HANDLE hConsoleOutput,_In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo);
_In_ HANDLE hConsoleOutput控制台屏幕缓冲区的句柄(前面讲的)_In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo指向 CONSOLE_CURSOR_INFO 结构的指针(前面讲的) 该结构为控制台屏幕缓冲区的光标提供新的规范。
如果该函数成功,则返回值为非零值 如果函数失败,则返回值为零
现在,我们先创建一个
CONSOLE_CURSOR_INFO结构体变量用于存放默认的游标信息 然后,用GetConsoleCursorInfo函数检索有关指定控制台屏幕缓冲区的游标大小和可见性的信息 接着,修改CONSOLE_CURSOR_INFO结构体变量中的值 再用SetConsoleCursorInfo函数设置有关指定控制台屏幕缓冲区的游标大小和可见性的信息 最后打印在屏幕上
=代码演示:(内有注释,不懂就看)
#include <stdio.h>
#include<Windows.h>
int main()
{
//获取句柄
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
//获取STD_OUTPUT_HANDLE标准输出的句柄
//定义一个包含游标信息的结构体
CONSOLE_CURSOR_INFO cursor_info = { 0 };
//检索句柄指定控制台屏幕缓冲区的游标大小和可见性的信息
GetConsoleCursorInfo(houtput, &cursor_info);
//将结构体中光标大小改为60%
cursor_info.dwSize = 60;
//设置有关指定控制台屏幕缓冲区的游标大小和可见性的信息
SetConsoleCursorInfo(houtput, &cursor_info);
//打印出新大小的值
printf("游标的新大小为%d%%\n\n", cursor_info.dwSize);
//将程序进行暂停以免程序结束
//方便观察结果
system("pause");
return 0;
}运行结果:

可以看到,我们修改成功,游标大小被修改为了60% 另外,这个还可以修改游标的可见性,大家可自行尝试
要注意: 在我们的控制台上的坐标系,与我们数学上的传统坐标系不一样
如图:

在我们的控制台上的坐标系中,有一个很重要的点: X轴的每个单位长度为1个普通字符的长度 而Y轴的每个单位长度为2个普通字符的长度
如图:

功能: 定义控制台屏幕缓冲区中字符单元的坐标。 坐标系 (0,0) 的原点位于缓冲区的顶部左侧单元格。 语法:
typedef struct _COORD {SHORT X;SHORT Y;} COORD, *PCOORD;成员:X:水平坐标或列值Y:垂直坐标或行值 演示: 定义并初始化一个COORD结构体COORD pos = { 30,10 };
功能: 设置指定控制台屏幕缓冲区中的光标位置。 语法:
BOOL WINAPI SetConsoleCursorPosition(_In_ HANDLE hConsoleOutput,_In_ COORD dwCursorPosition);
_In_ HANDLE hConsoleOutput控制台屏幕缓冲区的句柄(前面讲的)_In_ COORD dwCursorPosition指定新光标位置(以字符为单位)的 COORD 结构(前面讲的) 坐标是屏幕缓冲区字符单元的列和行 坐标必须位于控制台屏幕缓冲区的边界以内
如果该函数成功,则返回值为非零值 如果函数失败,则返回值为零
现在,我们可以先在
COODR结构体中存放要设置的光标 然后调用SetConsoleCursorPosition函数设置光标位置
代码演示:(内有注释,不懂就看)
#include <stdio.h>
#include<Windows.h>
int main()
{
//获取句柄
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
//获取STD_OUTPUT_HANDLE标准输出的句柄
//在`COODR结构体`中存放要设置的光标
COORD pos = { 20,10 };
//调用`SetConsoleCursorPosition`函数设置光标位置
SetConsoleCursorPosition(houtput, pos);
//将程序进行暂停以免程序结束
//方便观察结果
system("pause");
return 0;
}运行结果: 可以见得,光标先是定位到了(20,10)处,然后再打印接下来的东西

功能: 确定调用函数时按键是是否按下 以及上次调用
GetAsyncKeyState后是否按下了该键。 语法:SHORT GetAsyncKeyState( [in] int vKey );
[in] int vKey类型:int 一个虚拟密钥代码
Virtual-Key 代码 在键盘上,每个键都有一个对应的虚拟值 将这个虚拟值传给函数,该函数可以通过返回值来分辨该按键的状态
例如:(一部分) 下表显示了系统使用的虚拟键代码的符号常量名称、十六进制值和鼠标或键盘等效项,这些代码按数字顺序列出。

由于虚拟密钥代码有很多,大家可以自行查看,下面是链接: https://learn.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes
类型: SHORT 1 . 若返回的数据中,最高位为1,则说明该键现在的状态是按下 2 . 若返回的数据中,最高位为0,则说明该键现在的状态是没按下 3 . 若返回的数据中,最低位为1,则说明该键之前被按下过 4 . 若返回的数据中,最低位为0,则说明该键之前没被按下过 (二进制中)(特别注意按下和按下过)
现在,我们写一段代码来判断空格键是否被按下过 若返回的数据中,最低位为1,则说明该键之前被按下过 为了判断最低为是什么,我们可以将返回值 按位与1(&1) 结果是1最低位就是1;否则是0 (并且,为了方便按键,我们给系统Sleep休眠100ms)
运行代码:(内有注释,不懂就看)
#include <stdio.h>
#include<Windows.h>
int main()
{
//为了方便按键,我们给系统休眠100ms
Sleep(100);
//传入空格的虚拟值码,判断空格是否被按下
short ret = GetAsyncKeyState(VK_SPACE);
while (1)
{
if ((ret & 1) == 1)
{
printf("空格被按下过\n");
}
else
{
printf("空格没被按下过\n");
}
}
return 0;
}运行结果: (在Sleep代码运行完前按下空格)

可以看到,代码持续打印,说明空格之前被按下过
看到这里,我们已经学会了Win 32 API的一小部分知识
之后我们就可以开始着手设计一些简易游戏的代码了
当然,如果你想要了解更多更全的 Win 32 API 知识
可以去微软的官网(小编也是在那里查找的资料哦)
链接:https://learn.microsoft.com/zh-cn/windows/win32/api/
OK,本期Win 32 API的一部分内容详解到这里就结束了
下一期我会手把手教你完成贪吃蛇游戏,请敬请期待
本文有若有不足之处,希望各位兄弟们能给出宝贵的意见。谢谢大家!!!
新人,本期制作不易希望各位兄弟们能动动小手,三连走一走!!! 支持一下(三连必回QwQ)
本期资料来自于:
以及: