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

c语言游戏实战(10):坤坤的篮球回避秀

  前言:

这款简易版的球球大作战是博主耗时两天半完成的,玩家需要控制坤坤在游戏界面上移动,来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写,旨在帮助初学者了解游戏开发的基本概念和技巧。

在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:

游戏界面:游戏界面是一个矩形区域,玩家可以在这个区域内控制球的移动。

坤坤:玩家控制的坤坤可以在游戏界面内自由移动,按下特定的按键后可以跳跃。

篮球:篮球在游戏界面的正上方源源不断地生成,并下降。

坤坤触碰篮球:当坤坤触碰到上方掉下来的篮球时,坤坤的血量就会降低一格,一共五格血量降完为止。

接下来,我们将通过以下几个步骤来实现这个游戏:

1. 初始化游戏界面和模型的信息。

2. 处理键盘输入,实现玩家控制坤坤的移动和跳跃。

3. 生成足够数量的篮球。

4. 生成篮球,并控制其移动。

5. 检测篮球与坤坤之间的触碰关系,并减少相应的血量。

通过学习这个游戏的开发过程,初学者将能够掌握C语言编程和easyx图形库的基本技巧。

1. 前期准备

第一步:我们需要在easyx官网下载好easyx图形库。(具体操作可以去b站搜索相关视频)

第二步:按照下图的步骤将字符集改为多节字符集,因为如果使用的字符集只包含有限数量的字符,可能无法支持所有需要的字符,导致无法正确加载图像。因此,将字符集改为多字符集可以确保包含所有可能需要的字符,从而避免加载图像时出现错误或乱码问题。

2. 游戏的背景设置

游戏界面的长和宽根据背景图片的长宽(右键点击图片的属性可以查看)来设置,这里的背景图片有两张一张是游戏界面,另一张是游戏结束的图片。这里首先需要声明一个IMAGE类型的变量来存储加载的图片数据。这是后续对图片进行处理的基础,利用函数loadimage可以从本地文件中加载图片(尽量将游戏所需要的素材放在和代码的同一个目录里),最后利用putimage可以将图片绘制到窗口上来。

int main()
{Init();Itset();//设置窗口的长宽initgraph(Wide, Hight);//缓冲BeginBatchDraw();while (1){show();//刷新FlushBatchDraw();}closegraph;return 0;
}
//声明IMAGE类型的变量
IMAGE img[2];
//加载图片
loadimage(&img[0], "resource/微信图片_20240222202456.jpg");
loadimage(&img[1], "resource/微信图片_20240303132408.jpg");
//绘制图片
putimage(0, 0, &img[Img]);

3. 初始模型的信息

在这里篮球和坤坤的模型都是球,只是后面用图片覆盖而已。首先在游戏游戏界面的正上方生成多个球(具体数量自己定),然后在游戏的下方生成一个玩家控制的球,最后就是加载图片了。

初始化小球 

void Itset()
{//for (int i = 0; i < Ball_num; i++){Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}//玩家Player.x = Wide / 2;Player.r = 10;Player.y = Hight - Player.r * 4;
}

加载图片

因为loadimage函数只能加载图片,加载不了视频或者动图,所以我们需要将视频一帧一帧的加载上去,然后用循环绘制图片,这样就产生了一个动图的效果。

IMAGE kunkun[58];
IMAGE ball[Ball_num];loadimage(&kunkun[0], "resource/2月22日.png", 34, 34);loadimage(&kunkun[1], "resource/2月22日(1).png", 34, 34);loadimage(&kunkun[2], "resource/2月22日(2).png", 34, 34);loadimage(&kunkun[3], "resource/2月22日(3).png", 34, 34);loadimage(&kunkun[4], "resource/2月22日(4).png", 34, 34);loadimage(&kunkun[5], "resource/2月22日(5).png", 34, 34);loadimage(&kunkun[6], "resource/2月22日(6).png", 34, 34);loadimage(&kunkun[7], "resource/2月22日(7).png", 34, 34);loadimage(&kunkun[8], "resource/2月22日(8).png", 34, 34);loadimage(&kunkun[9], "resource/2月22日(9).png", 34, 34);loadimage(&kunkun[10], "resource/2月22日(10).png", 34, 34);loadimage(&kunkun[11], "resource/2月22日(11).png", 34, 34);loadimage(&kunkun[12], "resource/2月22日(12).png", 34, 34);loadimage(&kunkun[13], "resource/2月22日(13).png", 34, 34);loadimage(&kunkun[14], "resource/2月22日(14).png", 34, 34);loadimage(&kunkun[15], "resource/2月22日(15).png", 34, 34);loadimage(&kunkun[16], "resource/2月22日(16).png", 34, 34);loadimage(&kunkun[17], "resource/2月22日(17).png", 34, 34);loadimage(&kunkun[18], "resource/2月22日(18).png", 34, 34);loadimage(&kunkun[19], "resource/2月22日(19).png", 34, 34);loadimage(&kunkun[20], "resource/2月22日(20).png", 34, 34);loadimage(&kunkun[21], "resource/2月22日(21).png", 34, 34);loadimage(&kunkun[22], "resource/2月22日(22).png", 34, 34);loadimage(&kunkun[23], "resource/2月22日(23).png", 34, 34);loadimage(&kunkun[24], "resource/2月22日(24).png", 34, 34);loadimage(&kunkun[25], "resource/2月22日(25).png", 34, 34);loadimage(&kunkun[26], "resource/2月22日(26).png", 34, 34);loadimage(&kunkun[27], "resource/2月22日(27).png", 34, 34);loadimage(&kunkun[28], "resource/2月22日(28).png", 34, 34);loadimage(&kunkun[29], "resource/2月22日(29).png", 34, 34);loadimage(&kunkun[30], "resource/2月22日(30).png", 34, 34);loadimage(&kunkun[31], "resource/2月22日(31).png", 34, 34);loadimage(&kunkun[32], "resource/2月22日(32).png", 34, 34);loadimage(&kunkun[33], "resource/2月22日(33).png", 34, 34);loadimage(&kunkun[34], "resource/2月22日(34).png", 34, 34);loadimage(&kunkun[35], "resource/2月22日(35).png", 34, 34);loadimage(&kunkun[36], "resource/2月22日(36).png", 34, 34);loadimage(&kunkun[37], "resource/2月22日(37).png", 34, 34);loadimage(&kunkun[38], "resource/2月22日(38).png", 34, 34);loadimage(&kunkun[39], "resource/2月22日(39).png", 34, 34);loadimage(&kunkun[40], "resource/2月22日(40).png", 34, 34);loadimage(&kunkun[41], "resource/2月22日(41).png", 34, 34);loadimage(&kunkun[42], "resource/2月22日(42).png", 34, 34);loadimage(&kunkun[43], "resource/2月22日(43).png", 34, 34);loadimage(&kunkun[44], "resource/2月22日(44).png", 34, 34);loadimage(&kunkun[45], "resource/2月22日(45).png", 34, 34);loadimage(&kunkun[46], "resource/2月22日(46).png", 34, 34);loadimage(&kunkun[47], "resource/2月22日(47).png", 34, 34);loadimage(&kunkun[48], "resource/2月22日(48).png", 34, 34);loadimage(&kunkun[49], "resource/2月22日(49).png", 34, 34);loadimage(&kunkun[50], "resource/2月22日(50).png", 34, 34);loadimage(&kunkun[51], "resource/2月22日(51).png", 34, 34);loadimage(&kunkun[52], "resource/2月22日(52).png", 34, 34);loadimage(&kunkun[53], "resource/2月22日(53).png", 34, 34);loadimage(&kunkun[54], "resource/2月22日(54).png", 34, 34);loadimage(&kunkun[55], "resource/2月22日(55).png", 34, 34);loadimage(&kunkun[56], "resource/2月22日(56).png", 34, 34);for (int i = 0; i < Ball_num; i++){loadimage(&ball[i], "resource/5459.png_860.png", 36, 36);}

4. 绘制图片

图片是需要根据球来移动的,所以putimage函数的格式应该为:

putimage(x, y, Wide, Hight, &kunkun[a], 0, 0,SRCAND);
  1. x, y:图像左上角在窗口中的坐标。
  2. Wide, Hight:要绘制的图像的宽度和高度。
  3. &kunkun[a]:指向图像数据数组的指针,a是数组中图像数据的索引。
  4. 0, 0:源图像中要复制的区域的左上角坐标。

这样图片的位置就可以根据球的为止移动了。 

void show()
{srand((unsigned)time(NULL));//清屏函数cleardevice();//setbkcolor(WHITE);putimage(0, 0, &img[Img]);putimage(0, 0, &Heal[Health], SRCAND);for (int i = 0; i < Ball_num; i++){setfillcolor(RGB(229, 124, 77));solidcircle(Enemy[i].x, Enemy[i].y, Enemy[i].r);}putimage(Player.x - 14, Player.y - 14, Wide, Hight, &kunkun[a], 0, 0,SRCAND);for (int i = 0; i < Ball_num; i++){putimage(Enemy[i].x - 18, Enemy[i].y - 18, Wide, Hight, &ball[i], 0, 0, SRCAND);}
}

 5. 篮球的移动

随机生成8个随机数,然后根据这八个随机数在执行向下移动的同时执行向左或向右的指令。为了防止篮球的移动速度太快,我们需要加一个Sleep(10)函数给它降速。当篮球移动出游戏界面的时候我们让它重新生成。

void Enemy_move()
{srand((unsigned)time(NULL));for (int i = 0; i < Ball_num; i++){int direction = rand() % 8;if (direction == 0){Enemy[i].y++;Enemy[i].x--;}else if (direction == 1){Enemy[i].y++;Enemy[i].x++;}else if (direction == 2){Enemy[i].y += 2;Enemy[i].x += 2;}else if (direction == 3){Enemy[i].y += 2;Enemy[i].x -= 2;}else if (direction == 4){Enemy[i].y += 3;Enemy[i].x += 3;}else if (direction == 5){Enemy[i].y += 3;Enemy[i].x -= 3;}else if (direction == 6){Enemy[i].y += 4;Enemy[i].x -= 4;}else if (direction == 7){Enemy[i].y += 4;Enemy[i].x += 4;}if (Enemy[i].x <0 || Enemy[i].x>Wide || Enemy[i].y > Hight - Player.r * 3){Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}}
}

6. 玩家与球碰撞

生成游戏血条,每碰撞一次血条减少,并且重新生成篮球。

IMAGE Heal[6];loadimage(&Heal[5], "resource/微信图片_20240303142935.jpg");loadimage(&Heal[4], "resource/微信图片_20240303142958.jpg");loadimage(&Heal[3], "resource/微信图片_20240303142931.jpg");loadimage(&Heal[2], "resource/微信图片_20240303142926.jpg");loadimage(&Heal[1], "resource/微信图片_20240303142922.jpg");
//玩家与球碰撞
void collide()
{for (int i = 0; i < Ball_num; i++){if (Distance(Player.x, Player.y, Enemy[i].x, Enemy[i].y) < Player.r + Enemy[i].r && Health > 0){Health--;Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}}}

7. 人物的移动 

在这里需要用到GetAsyncKeyState(vk virtual key)函数获取异步按键状态,其中vk virtual key是虚拟键值,如果接受到这个虚拟键值,它会返回真。VK_UP、VK_LEFT、VK_RIGHT、0x20、0x41、0x44、0x57分别是上箭头键、左箭头键、右箭头键、空格键、a、d、w的虚拟键值。最后这里比较难处理的就是跳跃的这个动作了,我在这里设置人物跳跃后最高上升60个像素格,然后通过while循环循环上升每次上升5个像素个,如果是直接上升60个像素格的话,就是闪现了达不到跳跃的效果,在人物上升的同时其他动作是任然要进行的,所以我们还需要将这些动作函数打包放到这个人物跳跃的while循环当中。值得注意的是我们还需要在这个while循环中加一个Sleep(20)调节循环速度,使这里运动速度与主函数的while循环的运动速度一致。

void player_move()
{if (GetAsyncKeyState(VK_LEFT)|| GetAsyncKeyState(0x41)){if (Player.x > 0)Player.x -= Player_sleep;}if (GetAsyncKeyState(VK_RIGHT)|| GetAsyncKeyState(0x44)){if (Player.x < Wide)Player.x += Player_sleep;}if (Player.y == Hight - Player.r * 4){if (GetAsyncKeyState(0x20) || GetAsyncKeyState(0x57)|| GetAsyncKeyState(VK_UP)){BeginBatchDraw();while (Player.y > Hight - Player.r * 4 - 60){Sleep(20);Player.y -= 5;player_move();Enemy_move();show();collide();FlushBatchDraw();}}if (Health == 0){printf("\a");system("pause");exit(0);}}
}

效果展示:

坤坤的篮球回避秀

源码:

#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<windows.h>
#include<mmsystem.h>
#include<math.h>
#pragma comment(lib,"winmm.lib")
#define Wide 1280
#define Hight 720
#define Wide1 780
#define Hight1 286
#define Ball_num 20
#define Player_sleep 5
int Health = 5;
int sleep = 1;
int Img = 0;
struct Ball
{float x = 0;int y = 0;float r = 0;};
struct Ball Enemy[Ball_num];
struct Ball Player;
IMAGE img[2];
IMAGE kunkun[58];
IMAGE ball[Ball_num];
IMAGE Heal[6];
int a = 0;
//加载图片
void Init()
{loadimage(&img[0], "resource/微信图片_20240222202456.jpg");loadimage(&img[1], "resource/微信图片_20240303132408.jpg");loadimage(&Heal[5], "resource/微信图片_20240303142935.jpg");loadimage(&Heal[4], "resource/微信图片_20240303142958.jpg");loadimage(&Heal[3], "resource/微信图片_20240303142931.jpg");loadimage(&Heal[2], "resource/微信图片_20240303142926.jpg");loadimage(&Heal[1], "resource/微信图片_20240303142922.jpg");loadimage(&kunkun[0], "resource/2月22日.png", 34, 34);loadimage(&kunkun[1], "resource/2月22日(1).png", 34, 34);loadimage(&kunkun[2], "resource/2月22日(2).png", 34, 34);loadimage(&kunkun[3], "resource/2月22日(3).png", 34, 34);loadimage(&kunkun[4], "resource/2月22日(4).png", 34, 34);loadimage(&kunkun[5], "resource/2月22日(5).png", 34, 34);loadimage(&kunkun[6], "resource/2月22日(6).png", 34, 34);loadimage(&kunkun[7], "resource/2月22日(7).png", 34, 34);loadimage(&kunkun[8], "resource/2月22日(8).png", 34, 34);loadimage(&kunkun[9], "resource/2月22日(9).png", 34, 34);loadimage(&kunkun[10], "resource/2月22日(10).png", 34, 34);loadimage(&kunkun[11], "resource/2月22日(11).png", 34, 34);loadimage(&kunkun[12], "resource/2月22日(12).png", 34, 34);loadimage(&kunkun[13], "resource/2月22日(13).png", 34, 34);loadimage(&kunkun[14], "resource/2月22日(14).png", 34, 34);loadimage(&kunkun[15], "resource/2月22日(15).png", 34, 34);loadimage(&kunkun[16], "resource/2月22日(16).png", 34, 34);loadimage(&kunkun[17], "resource/2月22日(17).png", 34, 34);loadimage(&kunkun[18], "resource/2月22日(18).png", 34, 34);loadimage(&kunkun[19], "resource/2月22日(19).png", 34, 34);loadimage(&kunkun[20], "resource/2月22日(20).png", 34, 34);loadimage(&kunkun[21], "resource/2月22日(21).png", 34, 34);loadimage(&kunkun[22], "resource/2月22日(22).png", 34, 34);loadimage(&kunkun[23], "resource/2月22日(23).png", 34, 34);loadimage(&kunkun[24], "resource/2月22日(24).png", 34, 34);loadimage(&kunkun[25], "resource/2月22日(25).png", 34, 34);loadimage(&kunkun[26], "resource/2月22日(26).png", 34, 34);loadimage(&kunkun[27], "resource/2月22日(27).png", 34, 34);loadimage(&kunkun[28], "resource/2月22日(28).png", 34, 34);loadimage(&kunkun[29], "resource/2月22日(29).png", 34, 34);loadimage(&kunkun[30], "resource/2月22日(30).png", 34, 34);loadimage(&kunkun[31], "resource/2月22日(31).png", 34, 34);loadimage(&kunkun[32], "resource/2月22日(32).png", 34, 34);loadimage(&kunkun[33], "resource/2月22日(33).png", 34, 34);loadimage(&kunkun[34], "resource/2月22日(34).png", 34, 34);loadimage(&kunkun[35], "resource/2月22日(35).png", 34, 34);loadimage(&kunkun[36], "resource/2月22日(36).png", 34, 34);loadimage(&kunkun[37], "resource/2月22日(37).png", 34, 34);loadimage(&kunkun[38], "resource/2月22日(38).png", 34, 34);loadimage(&kunkun[39], "resource/2月22日(39).png", 34, 34);loadimage(&kunkun[40], "resource/2月22日(40).png", 34, 34);loadimage(&kunkun[41], "resource/2月22日(41).png", 34, 34);loadimage(&kunkun[42], "resource/2月22日(42).png", 34, 34);loadimage(&kunkun[43], "resource/2月22日(43).png", 34, 34);loadimage(&kunkun[44], "resource/2月22日(44).png", 34, 34);loadimage(&kunkun[45], "resource/2月22日(45).png", 34, 34);loadimage(&kunkun[46], "resource/2月22日(46).png", 34, 34);loadimage(&kunkun[47], "resource/2月22日(47).png", 34, 34);loadimage(&kunkun[48], "resource/2月22日(48).png", 34, 34);loadimage(&kunkun[49], "resource/2月22日(49).png", 34, 34);loadimage(&kunkun[50], "resource/2月22日(50).png", 34, 34);loadimage(&kunkun[51], "resource/2月22日(51).png", 34, 34);loadimage(&kunkun[52], "resource/2月22日(52).png", 34, 34);loadimage(&kunkun[53], "resource/2月22日(53).png", 34, 34);loadimage(&kunkun[54], "resource/2月22日(54).png", 34, 34);loadimage(&kunkun[55], "resource/2月22日(55).png", 34, 34);loadimage(&kunkun[56], "resource/2月22日(56).png", 34, 34);for (int i = 0; i < Ball_num; i++){loadimage(&ball[i], "resource/5459.png_860.png", 36, 36);}
}
//初始化小球的信息
void Itset()
{//for (int i = 0; i < Ball_num; i++){Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}//玩家Player.x = Wide / 2;Player.r = 10;Player.y = Hight - Player.r * 4;
}
void Enemy_move()
{srand((unsigned)time(NULL));for (int i = 0; i < Ball_num; i++){int direction = rand() % 8;if (direction == 0){Enemy[i].y++;Enemy[i].x--;}else if (direction == 1){Enemy[i].y++;Enemy[i].x++;}else if (direction == 2){Enemy[i].y += 2;Enemy[i].x += 2;}else if (direction == 3){Enemy[i].y += 2;Enemy[i].x -= 2;}else if (direction == 4){Enemy[i].y += 3;Enemy[i].x += 3;}else if (direction == 5){Enemy[i].y += 3;Enemy[i].x -= 3;}else if (direction == 6){Enemy[i].y += 4;Enemy[i].x -= 4;}else if (direction == 7){Enemy[i].y += 4;Enemy[i].x += 4;}if (Enemy[i].x <0 || Enemy[i].x>Wide || Enemy[i].y > Hight - Player.r * 3){Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}}
}
void show()
{srand((unsigned)time(NULL));cleardevice();putimage(0, 0, &img[Img]);putimage(0, 0, &Heal[Health], SRCAND);for (int i = 0; i < Ball_num; i++){setfillcolor(RGB(229, 124, 77));solidcircle(Enemy[i].x, Enemy[i].y, Enemy[i].r);}putimage(Player.x - 14, Player.y - 14, Wide, Hight, &kunkun[a], 0, 0,SRCAND);for (int i = 0; i < Ball_num; i++){putimage(Enemy[i].x - 18, Enemy[i].y - 18, Wide, Hight, &ball[i], 0, 0, SRCAND);}
}
//距离
int Distance(int x, int y, int x1, int y1)
{return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
//玩家与球碰撞
void collide()
{for (int i = 0; i < Ball_num; i++){if (Distance(Player.x, Player.y, Enemy[i].x, Enemy[i].y) < Player.r + Enemy[i].r && Health > 0){Health--;Enemy[i].x = Wide / 2;Enemy[i].y = 10;Enemy[i].r = 10;}}}
void player_move()
{if (GetAsyncKeyState(VK_LEFT)|| GetAsyncKeyState(0x41)){if (Player.x > 0)Player.x -= Player_sleep;}if (GetAsyncKeyState(VK_RIGHT)|| GetAsyncKeyState(0x44)){if (Player.x < Wide)Player.x += Player_sleep;}if (Player.y == Hight - Player.r * 4){if (GetAsyncKeyState(0x20) || GetAsyncKeyState(0x57)|| GetAsyncKeyState(VK_UP)){BeginBatchDraw();while (Player.y > Hight - Player.r * 4 - 60){Sleep(20);Player.y -= 5;player_move();Enemy_move();show();collide();FlushBatchDraw();}}if (Health == 0){printf("\a");system("pause");exit(0);}}
}
int main()
{Init();Itset();initgraph(Wide, Hight);BeginBatchDraw();while (1){Sleep(20);if (a <= 56){a++;}if (a > 56){a = 0;}if (Player.y < Hight - Player.r * 4){Player.y += 2;}if (sleep > 0){sleep--;}if (Health == 0)Img = 1;show();FlushBatchDraw();Enemy_move();player_move();collide();}closegraph;return 0;
}

相关文章:

c语言游戏实战(10):坤坤的篮球回避秀

前言&#xff1a; 这款简易版的球球大作战是博主耗时两天半完成的&#xff0c;玩家需要控制坤坤在游戏界面上移动&#xff0c;来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写&#xff0c;旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代…...

初学arp欺骗

首先准备一台靶机这里用虚拟机的win10 已知网关与ip地址&#xff08;怕误伤&#xff09; 现在返回kali从头开始 首先探测自己的网关 然后扫内网存活的ip 发现有3台 用nmap扫一下是哪几台 成功发现我们虚拟机的ip 现在虚拟机可以正常访问网络 接下来直接开梭 ip网关 返回虚拟机…...

ftp几个常见错误问题及解决办法

1、无法上传网页&#xff0c;FTP故障&#xff0d;提示“无法连接服务器”错误。 问题出现原因&#xff1a;FTP客户端程序设置问题&#xff0c;客户上网线路问题&#xff0c;ftp服务器端问题。 处理方法&#xff1a;建议客户使用CUTPFTP软件来上传客户的网页&#xff0c;在“F…...

鸿蒙App开发新思路:小程序转App

国家与国家之间错综复杂&#xff0c;在谷歌的安卓操作系统“断供”后&#xff0c;鸿蒙系统的市场化&独立化的道路便显而易见了。 2024年1月18日&#xff0c;华为宣布&#xff0c;不再兼容安卓的“纯血鸿蒙”--HarmonyOS NEXT鸿蒙星河版最终面世&#xff0c;并与2024年Q4正…...

C++17之std::invoke: 使用和原理探究(全)

C进阶专栏&#xff1a;http://t.csdnimg.cn/5mV9r 目录 1.概述 2.辅助类 3.原理分析 4.总结 1.概述 在之前的 C 版本中&#xff0c;要调用不同类型的可调用对象&#xff0c;需要使用不同的语法&#xff0c;例如使用函数调用运算符 () 来调用函数或函数指针&#xff0c;使用…...

shadertoy 游戏《来自星尘》摇杆复刻

正确的做法应该是上 noise 而不是叠加 sin 波&#xff0c;不过如果不想麻烦的话叠波还是一个不错的选择&#xff1a;整体效果如下&#xff0c;已经非常形似 直接上链接&#xff1a;Shader - Shadertoy BETA float radiusScale 0.9; float variation(vec2 v1, vec2 v2, float …...

获取PDF中的布局信息——如何获取段落

PDF解析是极其复杂的问题。不可能靠一个工具解决全部问题&#xff0c;尤其是五花八门&#xff0c;格式不统一的PDF文件。除非有钞能力。如果没有那就看看可以分为哪些问题。 提取文本内容&#xff0c;提取表格内容&#xff0c;提取图片。我认为这些应该是分开做的事情。python有…...

Laya2.13.3在Web条件下使用键盘控制相机移动

需求&#xff1a;在Laya开发时&#xff0c;常常没法移动相机来观察场内的环境&#xff0c;故制作一个移动相机的脚本来是实现此功能&#xff0c;目前先使用键盘后续会添加鼠标控制移动旋转等功能。 onEnable(){this.camera new Laya.Camera(0, 0.1, 100);this._tempVector3 n…...

centos系统服务器在Jenkins执行playwright UI自动化测试框架

centos系统服务器在Jenkins执行playwright UI自动化测试框架 1. centos7.9系统中安装playwright环境报错 playwright/driver/node: /lib64/libc.so.6: version `GLIBC_2.25 not found经过查找资料,playwright 仅支持Ubuntu系统,其他的Linux服务器系统不支持,为此采用docke…...

boost.redis崩溃的解决方法

使用boost.redis的协程一定要co_spawn在strand对象中。 正确的用法&#xff1a; boost::asio::co_spawn(boost::dasio::make_strand(ioc),XXXCoroutine(),boost::asio::detached ); 错误的用法&#xff1a; boost::asio::co_spawn(ioc,XXXCoroutine(),boost::asio::detache…...

蓝桥杯——123

123 二分等差数列求和前缀和数组 题目分析 连续一段的和我们想到了前缀和&#xff0c;但是这里的l和r的范围为1e12&#xff0c;明显不能用O(n)的时间复杂度去求前缀和。那么我们开始观察序列的特点&#xff0c;可以按照等差数列对序列进行分块。如上图&#xff0c;在求前10个…...

嵌入式基础知识-信号量,PV原语与前趋图

本篇来介绍信号量与PV原语的一些知识&#xff0c;并介绍其在前趋图上的应用分析。本篇的知识属于操作系统部分的通用知识&#xff0c;在嵌入式软件开发中&#xff0c;同样会用到这些知识。 1 信号量 信号量是最早出现的用来解决进程同步与互斥问题的机制&#xff08;可以把信…...

代码遗产:探索祖传代码的历史、挑战与现代融合艺术

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…...

Vue3:用vite创建Vue3项目

一、简介 vite是新一代前端构建工具&#xff0c;官网地址&#xff1a;https://vitejs.cn vite的优势如下&#xff1a; 轻量快速的热重载&#xff08;HMR&#xff09;&#xff0c;能实现极速的服务启动。对 TypeScript、JSX、CSS 等支持开箱即用。真正的按需编译&#xff0c;不…...

STM32 (2)

1.stm32编程模型 将C语言程序烧录到芯片中会存储在单片机的flsah存储器中&#xff0c;给芯片上电后&#xff0c;Flash中的程序会逐条进入到CPU中去执行&#xff0c;进而CPU去控制各种模块&#xff08;即外设&#xff09;去实现各种功能。 2.寄存器和寄存器编程 CPU通过控制其…...

docker部署nginx+反向代理配置/代理宿主机网段服务器

1、安装docker&#xff0c;并运行 2、拉取nginx镜像 docker pull nginx3、运行nginx容器&#xff0c;将文件拷贝至本地&#xff0c;并将nginx容器删除 #运行nginx容器 docker run -id --name mynginx -p 8080:80 nginx#将配置文件从容器内拷贝至本地 docker cp 容器ID:/et…...

初识Hive

官网地址为&#xff1a; Design - Apache Hive - Apache Software Foundation 一、架构 先来看下官网给的图&#xff1a; 图上显示了Hive的主要组件及其与Hadoop的交互。Hive的主要组件有&#xff1a; UI&#xff1a; 用户向系统提交查询和其他操作的用户界面。截至2011年&…...

Google发布Genie硬杠Sora:通过大量无监督视频训练最终生成可交互虚拟世界

前言 Sora 问世才不到两个星期&#xff0c;谷歌的世界模型也来了&#xff0c;能力看似更强大&#xff1a;它生成的虚拟世界自主可控 第一部分 首个基础世界模型Genie 1.1 Genie是什么 Genie是第一个以无监督方式从未标记的互联网视频中训练的生成式交互环境(the first gener…...

全球首台!未磁科技256通道无液氦脑磁图仪及芯片化原子磁力计正式发布

2024年2月3日&#xff0c;由北京未磁科技有限公司牵头的国家重点研发计划诊疗装备与生物医用材料重点专项“新型无液氦脑磁图系统研发”项目2023年度总结会暨2024年推进会顺利召开。会上发布了项目取得的重大成果——全球首台256通道无液氦脑磁图仪Marvel MEG Pro。此项重磅成果…...

openssl3.2 - exp - 内存操作(建立,写入,读取)配置

文章目录 openssl3.2 - exp - 内存操作(建立,写入,读取)配置概述笔记调试细节运行效果测试工程实现main.cppCMyOsslConfig.hCMyOsslConfig.cppEND openssl3.2 - exp - 内存操作(建立,写入,读取)配置 概述 我的应用的配置文件是落地加密的, 无法直接用openssl配置接口载入读取…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...