贪吃蛇代码实现与剖析(C语言)(中)

简介: 贪吃蛇代码实现与剖析(C语言)

一.Win32相关API的介绍

1.首先我们先介绍一下:什么是API?

也就是说我们Window系统给我们提供了很多函数,让我们可以通过调用这些函数去完成一些我们目前想要完成的任务

而这些函数服务的对象是应用程序

因此这些函数被称为API

1.控制台程序

1.什么是控制台程序

平常我们运⾏起来的⿊框程序其实就是控制台程序

就是这个Microsoft Visual Studio 调试控制台

在我们的Windows系统中,就有一个叫做命令提示符的工具

这个也是控制台程序

我们可以在Window系统中搜索cmd

然后打开,这个命令提示符就是控制台

我们要介绍的是:

2.命令提示符中设置控制台窗口的大小

我们可以设置控制台窗口的长宽:

比方说我现在想要让这个命令提示符的行数和列数设置为:

10行,50列

mode con cols=50 lines=10
• 1

我们输入这个命令,按下回车(就像是在Linux系统中输入命令行相同)

然后发现这个命令提示符变得特别小了

因此这就证明了我们是可以手动设置控制台大小的

3.控制台行和列的注意事项

然后我想让他变成一个正方形呢?

我们输入:让它行和列都变成30吧

mode con cols=30 lines=30
• 1

为什么不是一个正方形呢?

明明我输的是行30,列30啊

为什么会这样呢?

因为控制台中行的长度的基本单位和列的长度的基本单位不同

其实:

我们可以简单理解为:

控制台中每一行的长度==每一列的长度*2

那么我们想要构建一个正方形就可这样做了:

mode con cols=60 lines=30

这就是一个正方形了

4.VS2019中设置控制台窗口的大小

比方说我们想要一个15行,30列的一个正方形控制台窗口

mode con cols=30 lines=15

只需要包含Windows.h头文件

并且使用system函数

system("mode con cols=30 lines=15");

5.设置控制台名称

我们这个个界面还有一个贪吃蛇的名称

这个怎么设置呢?

跟刚才一样

只需要在VS代码里面加上

system("title 贪吃蛇");

不过我这里一开始的时候是无法修改这个控制台的名称

等到我写完贪吃蛇代码之后

控制台的名称就自然而然好了

所以大家如果在这一步无法修改名称的话,请先继续往后看

2.控制台屏幕坐标

COORD是Windows API中定义的一个结构体

它表示一个字符在控制台屏幕上的坐标

这个坐标系是这样的

typedef struct _COORD
{
  SHORT X;//X轴上的坐标
  SHORT Y;//Y轴上的坐标
}COORD,*PCOORD;
如果我们想要给这个控制台坐标赋值的话:
比方说我们给它的坐标赋值为:x轴:20,y轴:10
COORD pos = {20,10};
那么pos就是这个控制台上的对应位置的点

我们现在已经清楚了这个控制的坐标系的规则

但是还有一个问题:

这个控制台上的光标去哪了?

其实这个光标被我们隐藏了

那么我们该怎么样去隐藏这个光标呢?

别急,我们先来介绍一个函数:GetStdHandle

3.GetStdHandle

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

这是微软官方给的API的使用手册,大家可以看一下

Windows API索引

这个GetStdHandle函数的手册网址:GetStdHandle函数的手册网址

4.设置控制台光标状态

1.GetConsoleCursorInfo

2.CONSOLE_CURSOR_INFO

3.SetConsoleCursorInfo

也就是说我们想要隐藏光标,需要这样:

#include <stdio.h>
#include <Windows.h>
#include <stdbool.h>
int main()
{
  system("mode con cols=60 lines=20");
  HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//让handle具有能够操作控制台标准输出设备的能力/权限
  CONSOLE_CURSOR_INFO CursorInfo;//这个结构体就是定义光标信息的结构体
  GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
  CursorInfo.bVisible = false;//隐藏控制台光标的操作
  SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
  return 0;
}

不要忘了在C语言中使用bool类型的话需要包含stdbool.h头文件

这样我们就成功隐藏光标了

可是你这个控制台还能够在任意位置打印数据啊,

这肯定是通过设置光标位置做到的,那么如何才能设置光标位置呢?

4.SetConsoleCursorPosition

实例:

COORD pos = {30, 10};
 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(handle, pos);

成功在指定位置打印了hello world

5.SetPos函数的实现

那么既然我们需要很多次调整光标位置以便能够在任意位置写入数据

那么我们不妨设计一个函数SetPos来实现调整光标位置的操作呢?

于是我们就可以写出这样的函数

void SetPos(short x, short y)
{
  COORD pos = { x,y };
  HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
  SetConsoleCursorPosition(handle, pos);
}

6.GetAsyncKeyState

下面的问题来了:

我们想要玩这个游戏,就一定要能够接收我们的输入

我们既然是在电脑上玩,那就需要使用键盘去玩

那么就一定需要编译器能够在游戏运行的时候获取按键情况

因此微软WIN32API中就给了这么一个函数GetAsyncKeyState

作用是:获取按键情况

SHORT GetAsyncKeyState(
 int vKey
);

因此我们就可以让这个返回值跟1进行按位与

如果得出来的值是1:那么就代表这个值的最低位是1,也就是说这个键被按过

如果得出来的值是0:那么就代表这个值的最低位是0,也就是说这个键没有被按过

因此我们可以写出如下的宏

#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)

7.打印宽字符的实现

我们现在能够在屏幕上的任意位置打印数据,还能够隐藏光标,还能检测哪些键是否被按过

那不就可以了吗?

我们还漏了一点:

这个黑色原点:也就是蛇身

这个黑色五角星,也就是食物

这个白色方块:也就是墙体

这个是怎么打印出来的呢?

键盘上也没有啊

我们可以通过

搜狗输入法->输入方式->符号大全->里面就有

然后那不就行了吗?

是不行的

因为这三个字符属于宽字符(一个宽字符占2个字节,一个普通字符占1个字节),在VS的默认情况下我们是无法单独打印这些字符的

那么如何才能打印呢?

我们的准备工作终于做完了

下面就可以开始我们贪吃蛇游戏的具体实现了

相关文章
|
1月前
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
90 1
|
5天前
|
定位技术 API C语言
C语言——实现贪吃蛇小游戏
本文介绍了一个基于Windows控制台的贪吃蛇游戏的实现方法。首先,需调整控制台界面以便更好地显示游戏。接着,文章详细描述了如何使用Win32 API函数如`COORD`、`GetStdHandle`、`GetConsoleCursorInfo`等来控制控制台的光标和窗口属性。此外,还介绍了如何利用`GetAsyncKeyState`函数实现键盘监听功能。文中还涉及了`&lt;locale.h&gt;`库的使用,以支持本地化字符显示。
18 1
C语言——实现贪吃蛇小游戏
|
1天前
|
安全 C语言
在C语言中,正确使用运算符能提升代码的可读性和效率
在C语言中,运算符的使用需要注意优先级、结合性、自增自减的形式、逻辑运算的短路特性、位运算的类型、条件运算的可读性、类型转换以及使用括号来明确运算顺序。掌握这些注意事项可以帮助编写出更安全和高效的代码。
14 4
|
18天前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
|
18天前
|
存储 C语言 C++
数据结构基础详解(C语言) 顺序表:顺序表静态分配和动态分配增删改查基本操作的基本介绍及c语言代码实现
本文介绍了顺序表的定义及其在C/C++中的实现方法。顺序表通过连续存储空间实现线性表,使逻辑上相邻的元素在物理位置上也相邻。文章详细描述了静态分配与动态分配两种方式下的顺序表定义、初始化、插入、删除、查找等基本操作,并提供了具体代码示例。静态分配方式下顺序表的长度固定,而动态分配则可根据需求调整大小。此外,还总结了顺序表的优点,如随机访问效率高、存储密度大,以及缺点,如扩展不便和插入删除操作成本高等特点。
|
18天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
119 3
|
18天前
|
存储 算法 C语言
C语言手撕实战代码_二叉排序树(二叉搜索树)_构建_删除_插入操作详解
这份二叉排序树习题集涵盖了二叉搜索树(BST)的基本操作,包括构建、查找、删除等核心功能。通过多个具体示例,如构建BST、查找节点所在层数、删除特定节点及查找小于某个关键字的所有节点等,帮助读者深入理解二叉排序树的工作原理与应用技巧。此外,还介绍了如何将一棵二叉树分解为两棵满足特定条件的BST,以及删除所有关键字小于指定值的节点等高级操作。每个题目均配有详细解释与代码实现,便于学习与实践。
|
18天前
|
存储 算法 C语言
C语言手撕实战代码_二叉树_构造二叉树_层序遍历二叉树_二叉树深度的超详细代码实现
这段代码和文本介绍了一系列二叉树相关的问题及其解决方案。其中包括根据前序和中序序列构建二叉树、通过层次遍历序列和中序序列创建二叉树、计算二叉树节点数量、叶子节点数量、度为1的节点数量、二叉树高度、特定节点子树深度、判断两棵树是否相似、将叶子节点链接成双向链表、计算算术表达式的值、判断是否为完全二叉树以及求二叉树的最大宽度等。每道题目均提供了详细的算法思路及相应的C/C++代码实现,帮助读者理解和掌握二叉树的基本操作与应用。
|
18天前
|
存储 算法 C语言
C语言手撕实战代码_循环单链表和循环双链表
本文档详细介绍了用C语言实现循环单链表和循环双链表的相关算法。包括循环单链表的建立、逆转、左移、拆分及合并等操作;以及双链表的建立、遍历、排序和循环双链表的重组。通过具体示例和代码片段,展示了每种算法的实现思路与步骤,帮助读者深入理解并掌握这些数据结构的基本操作方法。
|
18天前
|
算法 C语言 开发者
C语言手撕实战代码_单链表
本文档详细介绍了使用C语言实现单链表的各种基本操作和经典算法。内容涵盖单链表的构建、插入、查找、合并及特殊操作,如头插法和尾插法构建单链表、插入元素、查找倒数第m个节点、合并两个有序链表等。每部分均配有详细的代码示例和注释,帮助读者更好地理解和掌握单链表的编程技巧。此外,还提供了判断子链、查找公共后缀等进阶题目,适合初学者和有一定基础的开发者学习参考。