当前位置: 首页 > news >正文

简单贪吃蛇小游戏的设计与实现

文章目录

  • 1、知识预备
    • 1.1 WIN32 API
      • 1.1.1 什么是WIN32 API
      • 1.1.2 了解部分WIN32 API
        • 1.1.2.1 控制台坐标
        • 1.1.2.2 控制台光标
        • 1.1.2.3 获取键盘按键情况
    • 2.1 宽字符
      • 2.1.1 C语言的国际化
      • 2.1.2 宽字符的打印
  • 2、 贪吃蛇游戏设计
    • 2.1 游戏开始
    • 2.2 游戏运行
      • 2.2.1 更新分数
      • 2.2.2 按键检测
      • 2.2.3 蛇的移动
    • 2.3 游戏结束
    • 2.4 游戏主逻辑的实现
  • 3、游戏最终效果

1、知识预备

1.1 WIN32 API

1.1.1 什么是WIN32 API

众所周知,Windows是一个操作系统,但同时它也是一个很大的服务中心,包含各种各样的服务,这些服务实质上就是函数,而由于这些函数服务的对象是应用程序,即Application,所以便把这些服务称为Appliication Programming Interface,简称API。WIN32 API 即Windows32位平台下的应用程序编程接口。

1.1.2 了解部分WIN32 API

1.1.2.1 控制台坐标

我们这个简单贪吃蛇小游戏的实现,是在控制台窗口中实现的,那么如何在VS中调出控制台窗口呢?

我们首先开启调试,将正常情况下的Windows终端打开,然后在最上端按鼠标右键转到设置,如下所示:
在这里插入图片描述

打开设置窗口后,找到这个选项:
在这里插入图片描述
将其由Windows终端改为Windows控制台主机,然后保存更改,这样之后无论是程序的调试还是正常执行,都是使用控制台窗口。至于为什么要使用控制台窗口,这是因为无论是之后所介绍的API的使用,还是想要对窗口大小、名称进行相应设置,都需要在控制台窗口中才可以完成。

在这里插入图片描述

在这里插入图片描述

这样,我们就成功打开了控制台窗口。

考虑到后续的游戏设计,此处大家必须对整个控制台的位置坐标有一个基本的了解。
整个控制台,左上角为0行0列,注意横为行,纵为列,其中,行代表的是纵坐标,列代表的是横坐标,所以画成一个坐标系的话就是这样:

在这里插入图片描述
那我们是如何去管理控制台的这些具体位置呢?
这就涉及到WIN32 API中定义的一个结构体COORD,表示一个字符在控制台屏幕上的坐标。

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

我们可以看到,这个结构体中有两个成员变量,一个代表横坐标x,另一个代表纵坐标y,即控制台中的横纵坐标

1.1.2.2 控制台光标

我们去定位控制台的坐标,想要实现在特定的坐标处打印相应的内容,这实际上是通过定位光标实现的.
WIN32 API中有为控制台的光标专门封装了一个结构体,用来管理光标的相应信息.

CONSOLE_CURSOR_INFO
这个结构体,包含有关控制台光标的信息
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
注:
dwSize是用来设置光标填充字符单元格的百分比的,此值介于1到100之间,从单元格底部的水平线条到完全填充单元格。
bVisible恰如其名,是用来控制光标是否可见,类型是BOOL类型,因此true为可见,false为不可见。

那我们如何获得控制台上的光标信息,又如何对这个光标信息进行修改,更重要的是如何对这个光标进行定位呢?

这就涉及到句柄的问题了。
句柄实质上就是一个用来标识对象或者项目的标识符,从用途上讲,获得了相应设备的句柄,我们就可以通过这个句柄对相应的设备进行操作。最常见的标准设备有两种:键盘和屏幕(即控制台窗口)。键盘对应标准输入,而屏幕则对应标准错误和标准输出。

要想获得句柄,就要使用一个专门用于获取句柄的函数:

HANDLE WINAPI GetStdHandle(
In DWORD nStdHandle
);
其中函数参数可取以下三种:
STD_INPUT_HANDLE 用于读取键盘的输入
STD_OUTPUT_HANDLE 用于输出,即对控制台进行相应的控制
STD_ERROR_HANDLE 标准错误设备

返回值类型HANDLE实质上是void* 类型,只不过被重命名了。

在这里插入图片描述

获取句柄的实例:

在这里插入图片描述

成功获取了句柄之后,我们就可以对控制台的光标进行相应的设置了。

在这里插入图片描述

在这里插入图片描述

除了调整光标的填充度和可见度,我们还可以设置光标的位置。

在这里插入图片描述

在这里插入图片描述

在后接的游戏涉及中,我们需要频繁设置光标位置,因此我们将光标位置设置的相关程序封装成一个函数SetPos.

在这里插入图片描述

1.1.2.3 获取键盘按键情况

SHORT GetAsyncKeyState(
int vKey
);

我们使用GetAsyncKeyState这个函数来实时获取键盘的按键情况.
使用这个函数时,我们需要将键盘按键对应的虚拟值传递给函数,对于不同的按键状态,函数会有不同情况的返回值进行对应.
返回值是一个16位的short类型数据.如果最高位是1,说明按键的状态是按下;如果最高位是0,说明按键的状态是抬起.而要判断按键是否按过(即按下后松手弹起),则通过最低位来进行判断,如果最低位被置为1,则说明按过;如果最低位是0,则说明没有按过.

我们在贪吃蛇小游戏中,要判断的是这个按键是否按过,因此我们需要对这个函数返回值的最低位进行判断.由于按键是否按过在贪吃蛇游戏中需要频繁进行判断,即需要频繁调用该函数,同时需要频繁对该函数的返回值进行判断,因此我们将这个判断的流程写成一个宏函数.

在这里插入图片描述

相关参考:

WINDOWS下的虚拟键码表
GetStdHandle
GetConsoleCursorInfo
SetConsoleCursorInfo
SetConsoleCursorPosition
GetAsyncKeyState

2.1 宽字符

2.1.1 C语言的国际化

C语言字符默认是采用ASCII编码的,而ASCII字符集采用的是单字节编码,且只使用了单字节中的低七位,最高位是没有使用的,这样总共能编码128个字符。但是在一些欧洲国家的语言中,128个字符是不够用的,因此一些欧洲国家就决定,再利用单字节中闲置的最高位进行编码,这样总共能编码256个字符,基本够用了。

但是对于亚洲国家而言,这显然是不够的,比如说中国,光汉字就多达十万左右。一个字节最多只能表示256个字符,所以必须用多个字节进行表示。比如,简体中文常见的编码方式GB2312,就是使用两个字节表示一个汉字,这样理论上最多可以表示65536个字符,满足日常的需求已经足够了。

而为了更好地适应C语言的国际化,C语言的标准中不断加入了国际化的支持。比如:加入了宽字符类型wchar_t 以及宽字符的输入和输出函数;还加入了locale.h头文件,其中提供了程序员针对特定地区调整程序行为的函数。

setlocale函数
char *setlocale(int category, const char *locale)
setlocale函数用来使程序行为本地化,可以针对一个类项进行修改,也可以针对所有类项。
该函数中的第一个参数就是要修改的类项,不同的类项名称不同,如果要修改所有类项,则使用LC_ALL。
该函数的第二个参数只有两种取值“C”和“”(即空字符串),当取值为"C"时,库函数按照默认方式执行;而当取值为“”时,便会切换到本地模式,程序会适应本地环境。注意,程序会默认执setlocale(LC_ALL,“C”)。

2.1.2 宽字符的打印

对于宽字符类型的数据,我们需要使用宽字符打印函数wprintf进行打印,不过宽字符类型的数据无论是定义还是打印时都需要加上一个字符L需要注意的是,要想正常实现宽字符的输入和输出,我们首先得使用setlocale函数,配置本地化。

在这里插入图片描述
前面提到了控制台窗口的坐标,那么一个宽字符在控制台窗口中占几行几列呢?
一个普通的char类型字符,即单字节字符,在控制台窗口中占一行一列;而一个二字节大小的宽字符,在控制台窗口中占一行两列。也就是说,宽字符相比于单字节字符,在横坐标,即x轴方向上多占一个单位,而在纵坐标,即y轴方向上,二者相同。

相关参考:
setlocale函数详解

2、 贪吃蛇游戏设计

2.1 游戏开始

我们最终要呈现的游戏效果如下所示:

这是第一个界面:

在这里插入图片描述

这是第二个界面:

在这里插入图片描述

这是第三个界面,同时也是我们的游戏界面:

在这里插入图片描述
第三个界面中,右侧文字为游戏说明文字,而左侧界面就是游戏界面,游戏界面可以分为三部分:墙体、蛇身和食物——这三种符号均用宽字符的形式进行打印。

所以,贪吃蛇游戏开始的设计流程如下:

  1. 首先,我们要调整控制台窗口。我们设想贪吃蛇的游戏地图大小为56 * 26,即横坐标方向上有28个方块(墙体),纵坐标方向上有26个方块,考虑到除墙体外,还有额外的文字说明,所以我们将控制台的窗口设置为100 * 30.
  2. 其次,在整个的游戏过程中,光标需要隐藏,防止光标对游戏效果造成影响。
  3. 最后,便是三个界面的依次打印,前两个界面打印完后,都需要添加system(“pasue”)和system(“cls”) 这两条语句,以实现按任意键继续以及清屏的功能。

整个游戏开始逻辑的代码如下:

在这里插入图片描述

考虑到游戏程序的编写过程中,需要频繁设置光标位置(即定位坐标),所以我们将光标位置的设置封装为一个函数。

在这里插入图片描述


前两个界面的代码实现如下:

在这里插入图片描述

在这里插入图片描述


第三个界面,我们要完成3个任务:打印地图、打印蛇以及打印第一个食物。

地图的打印,程序很简单,关键是要对于相关坐标计算清楚。控制台窗口行列,即纵横坐标,均从0开始,即0行0列开始,而要打印的墙体是宽字符,所以一个墙体,在纵坐标上占一个单位,在横坐标上占两个单位。所以地图的相应坐标范围应为:横坐标为0~55, 纵坐标为0 ~ 25.

在这里插入图片描述

在这里插入图片描述


接下来,便是蛇的打印。

在贪吃蛇中,我们使用什么结构来实现蛇呢?我们很容易能将蛇的一节节身体联想为单链表的一个个结点,因此我们使用链表这种数据结构来实现贪吃蛇。

首先,我们要将蛇身的结点封装成一个结构体,如下所示:

在这里插入图片描述

同时,贪吃蛇游戏中的这条贪吃蛇还会涉及到很多其它量:蛇走的方向、蛇走的快慢、蛇要吃的食物、每个食物的分数、所吃食物的总得分以及整个游戏的状态(比如说,蛇撞墙了,那么此时状态应为异常,即游戏应该终止)。

我们可以看到这一条贪吃蛇涉及到很多很多的量,为了便于管理和维护,我们将这些量全都封装到一个结构体中。

在这里插入图片描述

在这里插入图片描述

同时,我们将代表蛇身和食物的符号定义为标识符常量,方便程序的阅读。

在这里插入图片描述


这样,我们相关的准备工作便已进行完毕,可以开始蛇身的初始化以及打印。

我们知道,贪吃蛇游戏刚进入时,会在一定位置提供给你一条具有一定长度的蛇,所以我们要确定这个位置和长度。

一定的起始位置不妨定义为标识符常量:

在这里插入图片描述
蛇身的初始长度不妨定义为5,即包含5个链表结点。

注意:这里将POS_X定义为10,即定义为偶数,是有缘由的。因为无论是蛇身、墙体还是食物,都是宽字符,在横坐标上占两个单位,而横坐标从0开始,所以墙体相应的横坐标为0 ~ 1,2 ~ 3,…,54 ~ 55,我们可以发现,都是偶数开始的。而我们蛇身在横坐标上也是占两个单位,故蛇身的横向移动也是两个单位两个单位移动的,如果蛇身的起始位置不为偶数,那么撞墙时,就会出现蛇头一半在墙内,一半在墙外的情况,而这并不是我们所希望的.我们希望,蛇撞墙,便是蛇头与某个墙完全重合,故我们将蛇身的起始位置设为偶数。既然蛇身的起始位置为偶数,那么食物的横坐标起始位置也得为偶数,这样蛇才算完全吃到食物,而不会蛇头一半在食物里,一半在食物外。

初始化并打印贪吃蛇的相关代码如下:

在这里插入图片描述


打印完蛇身,最后要进行的是食物的打印。我们希望食物的生成是完全随机的,所以食物的横纵坐标我们使用rand函数进行生成,但同时,食物的坐标也有诸多限制——食物必须得在地图内且不能与墙重合,而且食物也不能与蛇身重合,最重要的是,食物的起始横坐标必须为偶数。

食物打印的代码如下所示:

在这里插入图片描述

通过以上这些过程,我们已成功实现游戏欢迎界面、游戏说明界面以及实际游戏界面中地图、蛇和食物的打印,即贪吃蛇游戏的开始流程GameStart设计完毕。

2.2 游戏运行

先观察一下我们的游戏界面:

在这里插入图片描述
游戏界面右方有一些信息,这些信息可以分为两类:一类是游戏的帮助信息(游戏规则的说明),另一类则是得分的记录,包括总得分和每个食物的分数。游戏的帮助信息只需要打印一次,而分数则需要不断更新。

所以,在正式进入游戏之前,我们还需要打印游戏的帮助信息,这个我们将其封装为一个函数。

在这里插入图片描述

现在,便正式进入游戏的模块。
游戏的模块可以分为三部分:分数的更新、按键的检测和蛇的移动。考虑到游戏模块是需要不断进行的,因此我们将整个游戏模块放在do-while循环中。

2.2.1 更新分数

更新分数的实现逻辑较为简单,将分数重新打印即可。

在这里插入图片描述但有一点需要注意,分数的更新,即重新打印,必须能够做到将上一次的分数完全覆盖,否则分数会出错。比如说,前一次的分数为10,后一次的分数为5,如果不做相应处理,而是直接打印,实际上显示的分数则为50,这就是没有完全覆盖带来的后果。这种情况,要想完全覆盖,可以在打印时设置数字所占的位数,以实现完全覆盖。正如上述代码,第二个printf函数中,我将数字所占位数设置为2(多的位数会自动补空格),并且设置为左对齐。

2.2.2 按键检测

在进行蛇的移动之前,我们首先要进行按键检测,因为有一些按键会对蛇的移动产生影响。

在讲述具体的程序之前,我们先将检测按键是否按过的程序定义为一个宏函数:

在这里插入图片描述
如果相应的按键按过,那么这个宏函数的结果为1,否则为0

接下来进行按键检测。我们有以下按键需要检测:

  1. 控制蛇上下左右移动的四个方向按键
  2. 控制蛇加速的F1键,控制蛇减速的F2键
  3. 游戏暂停的空格键,游戏退出的ESC键

方向键以及暂停、退出键的检测

在这里插入图片描述

注意上述方向的调整,方向不能任意变化,要确保蛇不会自己吃自己。
按空格键,游戏暂停;再按空格键,游戏继续。

加速与减速的设计:

蛇走的快慢,是通过睡眠时间的长短来调控的。由于我们将蛇走的逻辑设计为先睡一段时间再走,所以睡眠时间长,蛇走得就慢,睡眠时间短,蛇走得就快。

我们以睡眠时间来标记速度的挡位,总共分为7挡:50,100,150,200,250,300,350
其中200ms是初始挡位,即蛇的起始速度,从此速度开始,可以分别加速三档和减速三档。加速到50ms时,无法再加速,只能减速;减速到350ms时,无法再减速,只能加速。

不同的速度下,对应一个食物的分数也不同——速度快,食物分数高;速度慢,食物分数低。每加一次速,单个食物分数增加5分;每减一次速,单个食物分数减少5分。

具体的代码实现如下:

在这里插入图片描述

2.2.3 蛇的移动

按键检测完之后,就是蛇的移动。

在这里插入图片描述

蛇的移动该如何实现呢?
蛇身是由链表实现的,我们可以将蛇即将移动到的下一个位置看作一个蛇身结点,即重新malloc一个蛇身结点,而这个蛇身结点中,存储的是下一个位置的横纵坐标。在这种情况下,蛇的移动就变成了链表的头插与尾删,再将重新得到的链表遍历打印,即实现蛇走一步。

但是,我们还要考虑到蛇行进过程中的特殊情况。
如果蛇走到的下一个位置是食物,那么蛇吃食物,蛇身需要变长一节;如果蛇走到的下一个位置是墙体,蛇撞墙,游戏终止;如果蛇走到的下一个位置是蛇身的一节,蛇吃自己,那么游戏也要终止。
所以,根据蛇下一个位置坐标的情况,我们需要做出不同的处理,所以我们有以下的函数设计:

在这里插入图片描述

检测下一个位置的坐标是否为食物:

在这里插入图片描述

下一个坐标是食物,那么我们蛇就吃食物。注意,吃食物时,由于蛇身变长了一节,所以此时只需要进行链表头插,而不需要尾删。

在这里插入图片描述
注意:由于此时的蛇身打印,已经有之前打印好的蛇身作为基础,所以此时无需遍历打印蛇身,只需要将蛇即将走到的下一个位置打印上蛇身的图案即可。这样,我们就成功实现了蛇吃食物。

如果下一个位置不是食物,那么我们蛇就正常走一步,即链表头插和尾删,以及蛇身的打印。

在这里插入图片描述
注意,此处的打印也是在之前已经打印好的蛇身的基础上进行打印,所以不需要遍历打印,只需要进行一些修改——把蛇要走到的下一个位置打印为蛇身,蛇尾结点处打印两个空格进行覆盖。


如果下一个位置是食物的话,那么走到下一个位置肯定没问题;但如果下一个位置不是食物,蛇正常走一步,就有可能会撞到墙或者撞到自己,所以对于这种情况,我们需要进行额外的判断。

在这里插入图片描述
检测是否撞到墙,即拿蛇头结点的坐标与墙的坐标比对;检测是否撞到自身,即拿蛇头结点的坐标与蛇身剩余结点的坐标一个一个比对。

在这里插入图片描述

至此,贪吃蛇游戏运行的三大模块实现完毕。由于整个游戏的运行放在do-while循环中,所以要有循环条件,经过上述的分析,循环继续的条件显然为游戏的状态为OK.

在这里插入图片描述

2.3 游戏结束

游戏结束时,我们还需要进行相应的处理。
考虑到游戏结束的原因共有三种:主动退出、撞到墙以及撞到自己。所以相应地,我们也要有不同的对应说明。另外,在游戏结束后,我们还需要将蛇身的结点以及生成的食物所malloc出的堆区空间全部释放。

在这里插入图片描述

2.4 游戏主逻辑的实现

至此,我们游戏的三个核心函数GameStart()、GameRun()和GameEnd() 已经实现完毕,接下来便是在游戏的主逻辑中,将这三个函数串起来。

在这里插入图片描述


3、游戏最终效果

在这里插入图片描述

获取贪吃蛇游戏的全部代码,请访问博主的gitee仓库:简单的贪吃蛇小游戏实现

相关文章:

简单贪吃蛇小游戏的设计与实现

文章目录 1、知识预备1.1 WIN32 API1.1.1 什么是WIN32 API1.1.2 了解部分WIN32 API1.1.2.1 控制台坐标1.1.2.2 控制台光标1.1.2.3 获取键盘按键情况 2.1 宽字符2.1.1 C语言的国际化2.1.2 宽字符的打印 2、 贪吃蛇游戏设计2.1 游戏开始2.2 游戏运行2.2.1 更新分数2.2.2 按键检测…...

动态规划<五> 子数组问题(含对应LeetcodeOJ题)

目录 引例 经典LeetcodeOJ题 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 6.第六题 7.第七题 引例 OJ传送门 Leetcode<53> 最大子数组和 画图分析: 使用动态规划解决 1.状态表示 dp[i]表示以i位置为结尾的所有子数组中的最大和 2.状态转移方程 子数组的问题可以…...

计算机网络——期末复习(4)协议或技术汇总、思维导图

思维导图 协议与技术 物理层通信协议&#xff1a;曼彻斯特编码链路层通信协议&#xff1a;CSMA/CD &#xff08;1&#xff09;停止-等待协议&#xff08;属于自动请求重传ARQ协议&#xff09;&#xff1a;确认、否认、重传、超时重传、 &#xff08;2&#xff09;回退N帧协…...

在 RK3568 Linux 系统上使用 TUN 设备:详细教程

RK3568 是一个基于 ARM 架构的处理器,广泛应用于嵌入式系统和物联网设备。Linux 系统上的 TUN(网络隧道)设备提供了一个虚拟的网络接口,允许用户空间程序通过内核与网络栈进行交互。本文将详细介绍如何在 RK3568 上配置和使用 TUN 设备,适用于搭建 VPN 或容器网络等应用场…...

记录一次前端绘画海报的过程及遇到的几个问题

先看效果 使用工具 html2canvas import html2canvas from html2canvas// 绘画前的内容 我就不过多写了<div class"content" ref"contentRef" v-show"!imgShow"><img :src"getReplaceImg(friendObj.coverUrl)" alt"&qu…...

费舍尔信息矩阵全面讲述

费舍尔信息矩阵&#xff08;Fisher Information Matrix&#xff09; 费舍尔信息矩阵是统计学中一个非常重要的概念&#xff0c;尤其在参数估计、最大似然估计&#xff08;MLE&#xff09;和贝叶斯推断中具有广泛的应用。它反映了参数估计的不确定性程度&#xff0c;也可以用来…...

【CSS in Depth 2 精译_094】16.2:CSS 变换在动效中的应用(下)——导航菜单的文本标签“飞入”特效与交错渲染效果的实现

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第五部分 添加动效 ✔️【第 16 章 变换】 ✔️ 16.1 旋转、平移、缩放与倾斜 16.1.1 变换原点的更改16.1.2 多重变换的设置16.1.3 单个变换属性的设置 16.2 变换在动效中的应用 16.2.1 放大图标&am…...

webpack3 webpack4 webpack5 有什么区别

性能优化 Webpack 3 性能优化主要依赖开发者手动配置各种插件。例如&#xff0c;在代码分割方面&#xff0c;需要通过CommonsChunkPlugin来实现公共模块的提取&#xff0c;其配置相对复杂。如果配置不当&#xff0c;可能会导致模块重复打包等问题&#xff0c;影响构建效率和最终…...

vue2 升级为 vite 打包

VUE2 中使用 Webpack 打包、开发&#xff0c;每次打包时间太久&#xff0c;尤其是在开发的过程中&#xff0c;本文记录一下 VUE2 升级Vite 步骤。 安装 Vue2 Vite 依赖 dev 依赖 vitejs/plugin-vue2": "^2.3.3 vitejs/plugin-vue2-jsx": "^1.1.1 vite&…...

[创业之路-206]:《华为战略管理法-DSTE实战体系》- 6-关键成功因素法CSF

目录 一、概述 1、定义与起源 2、关键成功因素的定义 3、关键成功因素的来源 4、关键成功因素的确认方法 5、关键成功因素法的步骤 6、关键成功因素法的应用 7、关键成功因素法的优势与局限性 二、 关键成功因素法CSF的应用 1、企业战略管理 2、项目管理 3、绩效管…...

WebRTC服务质量(08)- 重传机制(05) RTX机制

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…...

Go的select的运行原理

Go语言中的select语句是一种专门用于处理多个通道&#xff08;channel&#xff09;操作的控制结构。其运行原理可以概括为以下几点&#xff1a; 1. 监听多个通道 select语句能够同时监听多个通道上的操作&#xff0c;这些操作可以是发送操作或接收操作。每个通道操作都对应se…...

操作002:HelloWorld

文章目录 操作002&#xff1a;HelloWorld一、目标二、具体操作1、创建Java工程①消息发送端&#xff08;生产者&#xff09;②消息接收端&#xff08;消费者&#xff09;③添加依赖 2、发送消息①Java代码②查看效果 3、接收消息①Java代码②控制台打印③查看后台管理界面 操作…...

3D坐标下,一点在某一线段上的左右方向的判定

3D坐标下&#xff0c;一点在某一线段上的左右方向的判定 代码 代码 #include <iostream> #include <Eigen/Dense>#define M_PI 3.1415926// 计算三点组成平面的参数和变换到XOY平面的变换矩阵 void computePlaneAndTransform(const Eigen::Vector3d& P1, cons…...

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…...

Linux高级--2.4.5 靠协议头保证传输的 MAC/IP/TCP/UDP---协议帧格式

任何网络协议&#xff0c;都必须要用包头里面设置写特殊字段来标识自己&#xff0c;传输越复杂&#xff0c;越稳定&#xff0c;越高性能的协议&#xff0c;包头越复杂。我们理解这些包头中每个字段的作用要站在它们解决什么问题的角度来理解。因为没人愿意让包头那么复杂。 本…...

【UE5 C++课程系列笔记】14——GameInstanceSubsystem与动态多播的简单结合使用

效果 通过在关卡蓝图中触发GameInstanceSubsystem包含的委托&#xff0c;来触发所有绑定到这个委托的事件&#xff0c;从而实现跨蓝图通信。 步骤 1. 新建一个C类 这里命名为“SubsystemAndDelegate” 引入GameInstanceSubsystem.h&#xff0c;让“SubsystemAndDelegate”继承…...

PyQt实战——随机涂格子的特色进度条(十一)

系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序入口QMainWindow&#xff08;三&…...

.NET 8.0 项目升级到 .NET 9.0

本文项目从.NETCore3.1开始一直延续到目前&#xff0c;如果您没有升级过&#xff0c;请参考以下文章&#xff1a; .Net Core 2.2 升级到 .Net Core 3.1&#xff1a;https://blog.csdn.net/hefeng_aspnet/article/details/131259537 NetCore3.1或Net6.0项目升级到Net7.0&#x…...

用Python写炸金花游戏

文章目录 **代码分解与讲解**1. **扑克牌的生成与洗牌**2. **给玩家发牌**3. **打印玩家的手牌**4. **定义牌的优先级**5. **判断牌型**6. **确定牌型优先级**7. **比较两手牌的大小**8. **打印结果** 完整代码 以下游戏规则&#xff1a; 那么我们要实现的功能&#xff0c;就是…...

深度学习中的并行策略概述:2 Data Parallelism

深度学习中的并行策略概述&#xff1a;2 Data Parallelism 数据并行&#xff08;Data Parallelism&#xff09;的核心在于将模型的数据处理过程并行化。具体来说&#xff0c;面对大规模数据批次时&#xff0c;将其拆分为较小的子批次&#xff0c;并在多个计算设备上同时进行处…...

电商平台能挡住恶意网络爬虫的攻击吗?

爬虫盗取电商数据的步骤 爬虫技术作为一种数据获取工具&#xff0c;正逐渐成为电商平台的一大隐患。网络爬虫不仅能够获取商家关键信息并滋生仿冒网站&#xff0c;还能收集用户敏感信息&#xff0c;对用户的财产安全和隐私造成严重威胁。同时&#xff0c;爬虫攻击还会扰乱正常…...

Jenkins安装方法二

配置环境 和 Jenkins 官方的 yum 源之后进行安装 # 关闭防火墙 $ sudo systemctl stop firewalld $ sudo systemctl disable firewalld# 安装 EPEL 源 $ sudo yum install -y epel-release # 安装 wget $ sudo yum install -y wget# 配置 Jenkins 官方 yum 源 $ sudo wget -O /…...

Nginx性能优化全方案:打造一个高效服务器

提到前面&#xff1a;一个热衷技术&#xff0c;反对八股的资深研发&#xff0c;不卖课不引流&#xff0c;专注分享高质量教学博客。 如果觉得文章还不错的话&#xff0c;可以点赞收藏关注 支持一下&#xff0c;持续分享高质量技术博客。 如果有什么需要改进的地方还请大佬指出❌…...

【每日学点鸿蒙知识】沙箱目录、图片压缩、characteristicsArray、gm-crypto 国密加解密、通知权限

1、HarmonyOS 如何创建应用沙箱目录&#xff1f; 下载文件&#xff0c;想下载到自己新建的应用沙箱目录&#xff0c;有什么方法实现吗&#xff1f; fs.mkdir可以创建目录 参考文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis…...

XMLHttpRequest的基础知识

get请求 const xml new XMLHttpRequest(); xml.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true); xml.onreadystatechange function () {if (xml.readyState 4 && xml.status 200) {console.log(xml.responseText);} }…...

学习笔记(C#基础书籍)-- C#基础篇

&#xff08;12.24&#xff09; C#介绍&#xff1a;《第一章》 特点&#xff1a;语法简洁&#xff0c;面向对象&#xff0c;支持绝大部分的web标准&#xff0c;强大的安全机制&#xff08;垃圾回收器&#xff09;&#xff0c;兼容性好&#xff08;遵循.NET的公共语言规范【CL…...

现在有什么赛道可以干到退休?

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;点击跳转到网站 &#xff0c;对人工智能感兴趣的小伙伴可以点进去看看。 最近&#xff0c;一则“90后无论男女都得65岁以后退休”的消息在多个网…...

【VScode】第三方GPT编程工具-CodeMoss安装教程

一、CodeMoss是什么&#xff1f; CodeMoss是一款集编程、学习和办公于一体的高效工具。它兼容多种主流平台&#xff0c;包括VSCode、IDER、Chrome插件、Web和APP等&#xff0c;支持插件安装&#xff0c;尤其在VSCode和IDER上的表现尤为出色。无论你是编程新手还是资深开发者&a…...

选择屏幕的用法

**************************定义控件*********************************** SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-002. SELECT-OPTIONS bukrs FOR iloa-bukrs . "公司代码 SELECT-OPTIONS swerk FOR iloa-swerk OBLIGATORY . "工厂 SELECT-O…...

VirtualBox下ubuntu23.04使用主机串口以及使用 minicom 进行串口调试

VirtualBox下ubuntu23.04使用主机串口以及使用 minicom 进行串口调试 一、打开设备管理器看主机&#xff08;Window系统&#xff09;是否识别出串口&#xff0c;我这边显示的串行通信端口是COM3 二、打开VirtualBox&#xff0c;设置串口和USB设备 串口设置&#xff1a; 启用…...

CH340系列芯片驱动电路·CH340系列芯片驱动!!!

目录 CH340基础知识 CH340常见类型 CH340引脚功能讲解 CH340驱动电路 CH340系列芯片数据手册 编写不易&#xff0c;仅供学习&#xff0c;请勿搬运&#xff0c;感谢理解 常见元器件驱动电路文章专栏连接 LM7805系列降压芯片驱动电路降压芯片驱动电路详解-CSDN博客 ME62…...

Unity中使用环形缓冲区平滑抖动值

环形缓冲数据结构&#xff0c;就是如下图一样的一个收尾相接的列表 在index指针指到4时&#xff0c;再往里添加数据&#xff0c;index就会指向0&#xff0c;并覆盖已有数据。 如何绘制Sin函数&#xff0c;请看下面一篇文章 Unity中如何实现绘制Sin函数图像-CSDN博客 接下来要…...

如何通过HTTP API插入或更新Doc

本文介绍如何通过HTTP API向Collection中插入或更新Doc。 说明 若调用本接口时Doc Id已存在&#xff0c;则等同于更新Doc&#xff1b;Doc Id不存在&#xff0c;则等同于插入Doc。 若调用本接口时不指定Doc Id&#xff0c;则等同于插入Doc&#xff0c;DashVector会自动生成Doc …...

RTMW:实时多人2D和3D 全人体姿态估计

单位&#xff1a;上海AI实验室 代码&#xff1a;mmpose/tree/main/projects/rtmpose 系列文章目录 RTMO: 面向高性能单阶段的实时多人姿态估计 目录 系列文章目录摘要一、背景二、相关工作2.1 自上而下的方法。2.2 坐标分类。2.3 3D Pose 3 实验方法3.1.1 任务限制3.1.3训练技…...

《Java源力物语》-3.空值猎手

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” \quad 夜色渐深&#xff0c;在一处偏僻小径上&#xff0c;月光透过浓密的源力云层&#xff0c;在地面上投下斑驳的光影。String正独自练习着刚从…...

macrodroid通过http请求控制手机运行宏

macrodroid adb命令 adb shell pm grant com.arlosoft.macrodroid android.permission.WRITE_SECURE_SETTINGS例:http请求手机播放指定MP3文件 声音素材_电量过低提醒 新建一个宏 添加触发器-连接-http服务器请求 路径随意填,最好不要有特殊符号,不然浏览器识别链接会出错,…...

Redis分片集群+MQ处理高并发

Redis的三大集群模式&#xff1a;主从复制、哨兵模式和Cluster模式。每种模式都有其特点和应用场景&#xff0c;具体如下&#xff1a; 主从复制模式&#xff1a;适用于数据备份和读写分离场景&#xff0c;配置简单&#xff0c;但在主节点故障时需要手动切换。哨兵模式&#xff…...

Linux内核 -- UIO (User-space I/O) 简介与使用笔记

UIO (User-space I/O) 简介 UIO (User-space I/O) 是 Linux 内核提供的一种机制&#xff0c;用于简化设备驱动的开发。它将设备的硬件资源&#xff08;如内存映射、中断等&#xff09;通过简单的接口暴露给用户空间程序&#xff0c;从而使用户可以在用户空间编写复杂的设备逻辑…...

《计算机组成及汇编语言原理》阅读笔记:p86-p115

《计算机组成及汇编语言原理》学习第 6 天&#xff0c;p86-p115 总结&#xff0c;总计 20 页。 一、技术总结 1.if statement 2.loop 在许多编程语言中&#xff0c;有类种循环&#xff1a;一种是在程序开头检测条件(test the condition),另一种是在程序末尾检测条件。 3.C…...

Python爬虫实战(保姆级登网页信息爬取教程)

此blog为爬虫实战教学&#xff0c;代码已附上&#xff0c;可以复制运行。若要直接看实战代码翻到博客后半部分。 本文使用selenium库进行爬虫&#xff0c;实现爬取数据操作&#xff0c;此库是通过模仿用户的操作进行对页面的处理。了解了这个思维模式&#xff0c;可以对代码进…...

探索CSDN博客数据:使用Python爬虫技术

探索CSDN博客数据&#xff1a;使用Python爬虫技术 在数字化的浪潮中&#xff0c;数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台&#xff0c;汇聚了海量的技术博客与文章&#xff0c;成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…...

PPT画图——如何设置导致图片为600dpi

winr&#xff0c;输入regedit打开注册表 按路径找&#xff0c;HKEY_CURRENT_USER\Software\Microsoft\Office\XX.0\PowerPoint\Options&#xff08;xx为版本号&#xff0c;16.0 or 15.0或则其他&#xff09;。名称命名&#xff1a;ExportBitmapResolution 保存即可&#xff0c;…...

uniapp——APP读取bin文件,解析文件的数据内容(二)

文章目录 读取bin文件内容&#xff0c;发送给蓝牙设备&#xff1b;上传文件返回数据格式通过URL路径获取文件对象&#xff0c;读取文件的数据内容file对象返回数据格式 读取bin文件内容&#xff0c;发送给蓝牙设备&#xff1b; 上传文件&#xff0c;根据返回路径&#xff0c;解…...

Paddler负载均衡器

Paddler负载均衡器 Paddler本身是用Go语言编写的,没有直接的Python接口,但可以通过以下方式在Python中使用: 执行命令行调用 在Python中可以使用 subprocess 模块来调用Paddler的命令行工具,实现负载均衡功能 。例如: import subprocessdef start_paddler_agent():com…...

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串&#xff1f;2、两个引号之间加上空格 好的&#xff0c;我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别&#xff0c;以及它们在 SQL 查询中的作用&#xff1a; 1. we_chat_union_id IS NOT NULL 含…...

clicbot可立宝编程 易错归纳笔记

1、屏幕播放表情模块和等待时间 易错点1&#xff1a; (1)等待时间&#xff1a; (a)不是等上一个代码执行完&#xff0c;再执行等待时间&#xff0c;这是错误的。 (b)等待时间上面的代码1刚开始执行&#xff0c;上面的代码2也刚开始执行&#xff0c;不是等到代码1执行完&#xf…...

MySQL 数据”丢失”事件之 binlog 解析应用

事件背景 客户反馈在晚间数据跑批后,查询相关表的数据时,发现该表的部分数据在数据库中不存在 从应用跑批的日志来看,跑批未报错,且可查到日志中明确显示当时那批数据已插入到数据库中 需要帮忙分析这批数据丢失的原因。 备注:考虑信息敏感性,以下分析场景测试环境模拟,相关数据…...

基于人工智能时代政务智慧转型的实现前景初探

去年6月&#xff0c;我有幸聆听了由华政公共管理与政治学院精心组织的2019年MPA研究生高端论坛&#xff0c;上午场&#xff1a;由董海军&#xff08;中共上海市委机构编制委员会办公室处长&#xff09;主讲的深化机构改革的探索与实践&#xff0c;以及下午场&#xff1a;由束金…...

【论文笔记】Visual Alignment Pre-training for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Alignment Pre-tra…...