【游戏专区】飞机大战

devtools/2024/9/20 2:02:38/ 标签: 游戏, 算法, 开发语言

打过飞机的人都知道,不是那么好打滴,求得麻袋,甩掉你那脑子里的黄色信息。活不多说,我们开始吧。

1、easyX的原理

基于Windows图形编程,将Windows下的复杂程序过程进行封装,仅给用户提供一个简单熟悉的接口。用户对于图形库中函数的调用,最终都会由Windows底层的API实现。

2、easyX的安装

仅支持vs系列

点击跳转

平常使用那个版本就点击对应的安装按钮即可。

3,图片资源

链接:点击获取图片
提取码:1111

4,创建窗口

窗口我们需要创建多大呢,

具体实现怎么操作,我们开始写代码

窗口是有了,但是我们如何将图片绘制出来呢

5,定义飞机结构

想想我们飞机需要哪些结构,坐标,血量还有什么呢

//创建飞机结构
typedef struct Plane
{int x;//飞机坐标int y;bool isDie;//是否健在int width;//宽度int height;//长度int frame;//当前帧int hp;//血量int type;//敌机类型
}Plane;

有了飞机的结构以及初始化,我们是不是还需要将其加载进入
飞机图片

6,透明贴图函数(可直接复制,使用也是可以的)

#include "aircraft.h"//把像素的颜色拆解出来 ARGB
typedef struct _ARGB {byte a;byte r;byte g;byte b;
}ARGB;
//把颜色拆分
ARGB color2Argb(DWORD c) {ARGB res;res.r = (byte)c;res.g = (byte)(c >> 8);res.b = (byte)(c >> 16);res.a = (byte)(c >> 24);return res;
}
DWORD argb2Color(ARGB c) {DWORD t = RGB(c.r, c.g, c.b);return ((DWORD)c.a) << 24 | t;
}
//把色彩图转成黑白图
void toGray(IMAGE* src) {DWORD* psrc = GetImageBuffer(src);for (int i = 0; i < src->getwidth() * src->getheight(); i++) {//获取每一个像素点的颜色值ARGB t = color2Argb(psrc[i]);//灰度图,求三个或者四个颜色值的均值byte arv = (t.r + t.g + t.b) / 3;ARGB res = { t.a,arv,arv,arv };psrc[i] = argb2Color(res);}
}
/*
* @png透明贴图
*/
void drawImg(int x, int y, IMAGE* src) {// 变量初始化DWORD* pwin = GetImageBuffer();//窗口缓冲区指针DWORD* psrc = GetImageBuffer(src);//图片缓冲区指针int win_w = getwidth();//窗口宽高int win_h = getheight();int src_w = src->getwidth();//图片宽高int src_h = src->getheight();//计算贴图的实际长宽int real_w = (x + src_w > win_w) ? win_w - x : src_w;//处理超出右边界int real_h = (y + src_h > win_h) ? win_h - y : src_h;//处理超出右边界if (x < 0) {//处理超出左边界psrc += -x;real_w -= -x;x = 0;}if (y < 0) {//处理超出右边界psrc += (src_w * -y);real_h -= -y;y = 0;}//修正贴图起始位置pwin += (win_w * y + x);//实现透明贴图for (int iy = 0; iy < real_h; iy++) {for (int ix = 0; ix < real_w; ix++) {byte a = (byte)(psrc[ix] >> 24);//计算透明通道的值[0,256] 0为完全透明 255完全不透明if (a > 100) {pwin[ix] = psrc[ix];}}//换到下一行pwin += win_w;psrc += src_w;}
}

当我们写到这里,只需要将绘制飞机的(putimage)替换成(drawLmg),就已经可以实现飞机的动态刷新了

7,飞机的移动

那我们要去移动飞机吧,不然他还只是一张图片,我们要写飞机的移动,就必须考虑它的边界问题。

知道了这些,我们就可以开始写代码了

当我们写完这个,你就会发现你的飞机走的非常快,这是我们电脑在处理帧的时候非常的迅速,所以我们还需要一个定时器,每秒刷新60帧,应该已经足够。

//参数:frameRate 帧数
void timerFunction(int frameRate) {clock_t startTime, currentTime;long elapsed;// 计算每一帧的毫秒数int ms_per_frame = 1000 / frameRate;// 获取初始时间startTime = clock();while (1) {// 获取当前时间currentTime = clock();// 计算已经过去的时间(以毫秒为单位)elapsed = (currentTime - startTime) * 1000;// 如果已经过去的时间超过了下一帧的时间间隔,则输出一帧if (elapsed >= ms_per_frame) {// 更新初始时间startTime = currentTime;// 暂停一段时间,使得每秒输出指定的帧率Sleep(1); // 暂停 1 毫秒break;}}
}

8,子弹的初始化绘制以及移动

现在我们就来定义子弹的结构

//子弹结构
typedef struct Bullet
{int x;//坐标int y;bool isDie;//是否出界面以及碰到敌机}Bullet;

子弹的初始化,我们也可以在初始化函数中进行调用

初始化完成后,我们还需加载资源以及绘制它

//子弹图片有两张
static IMAGE img_bullet[2];//加载子弹图片
loadimage(img_bullet + 0, "images/bullet1.png");
loadimage(img_bullet + 1, "images/bullet2.png");

但是,当我们有了这些依旧无法发射子弹,我们设计的是需要空格去发射的,所以,我们还需要再移动飞机的函数中写一个发射子弹的判断

这是因为我们发射子弹太快,重叠了,而且我们的子弹只会停留在我们发射的位置,不会移动,所有有了目标,接下来就好办多了。

我们可以写一个定时器,让它隔几微妙后才能发射

/*
类概述:
私有成员变量: std::vector<std::chrono::steady_clock::time_point> startTimes:存储每个计时器的起始时间,通过其ID进行标识。
构造函数:
Timer(): 默认构造函数。
方法:
bool hasElapsed(int ms, int id): 检查指定ID的计时器是否经过了ms毫秒。
*/
class Timer {
private:std::vector<std::chrono::steady_clock::time_point> startTimes;public:Timer() {}bool hasElapsed(int ms, int id) {if (id >= startTimes.size()) {startTimes.resize(id + 1);startTimes[id] = std::chrono::steady_clock::now();return true; // Treat as elapsed since this is the first time for this timer}auto now = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - startTimes[id]);if (duration.count() >= ms) {startTimes[id] = now;return true;}return false;}
};

接下来就是子弹的移动

所以呢,这样看我们要写的移动就是Y轴的递减过程,飞出界外或者碰到敌人,我们将其置为false就可以了。(很容易写吧)

9,创建敌机

我们现在需要什么,当然是敌人啊

我要打十个,敌人的结构我们可以直接用本机的结构,我们直接初始化敌机,当然,我们敌机的照片也是有好几种的,我这里只加载了两种敌对飞机,如果你们想,其实可以在等主机把小飞机打完之后,绘制打飞机,大飞机的血量可以多点,大飞机也可以发射子弹,当主角解决完大飞机后,可以产生一个界面吗,问其是否要继续挑战,进入下一关,逻辑也是相当简单的。

10,检测子弹是否打到敌机以及敌机是否碰到本机

到这里,我们就完成了第一关的制作,后续如果可以根据你们的意愿去做其他的处理

11,aircraft.h

#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <easyx.h>
#include <chrono>
#include <vector>#define MOVE 5
#define graph_height 700
#define graph_width 480
#define ENEMY_NUM 10//敌机数量#define BULLET_NUM 25//子弹数量
//子弹图片有两张
static IMAGE img_bullet[2];
static IMAGE img_bk;//背景图
static IMAGE img_gamer[2];//飞机图片
static IMAGE img_enemy[2][2];//敌机图片//创建飞机结构
typedef struct Plane
{int x;//飞机坐标int y;bool isDie;//是否健在int width;//宽度int height;//长度int frame;//当前帧int hp;//血量int type;//敌机类型
}Plane;//子弹结构
typedef struct Bullet
{int x;//坐标int y;bool isDie;//是否出界面以及碰到敌机}Bullet;
//敌机类型
enum enemyType
{BIG,//大飞机SMALL//小
};//资源加载
void Resource();
//绘制函数
void draw(Plane* gamer,Bullet* bullet, Plane* enemy);
//初始化函数
void init(Plane* gamer, Bullet* bullet, Plane* enemy);
//透明贴图函数
void drawImg(int x, int y, IMAGE* src);
//定时器
void timerFunction(int frameRate);
//更新数据
void Updata(Plane* gamer, Bullet* bullet, Plane* enemy);
//void updateEnemyStatus(Plane* enemy);
void checkCollision(Plane* gamer,Plane* enemy, Bullet* bullet);
void createEnemy(Plane* enemy);

12,aircraft.cpp

#include "aircraft.h"class Timer {
private:std::vector<std::chrono::steady_clock::time_point> startTimes;public:Timer() {}bool hasElapsed(int ms, int id) {if (id >= startTimes.size()) {startTimes.resize(id + 1);startTimes[id] = std::chrono::steady_clock::now();return true; // 重启计数器}auto now = std::chrono::steady_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - startTimes[id]);if (duration.count() >= ms) {startTimes[id] = now;return true;}return false;}
};
Timer timer;void enemyHP(int i, Plane* enemy)
{int flag = rand() % 10;if (flag >= 0 && flag <= 1){enemy[i].type = BIG;enemy[i].hp = 3;enemy[i].width = 169;enemy[i].height = 230;}else{enemy[i].type = SMALL;enemy[i].hp = 1;enemy[i].width = 57;enemy[i].height = 43;}
}
//资源加载
void Resource()
{//加载资源函数loadimage(&img_bk, "images/background.png");//加载玩家飞机图片loadimage(&img_gamer[0], "images/me1.png");loadimage(&img_gamer[1], "images/me2.png");//加载子弹图片loadimage(img_bullet + 0, "images/bullet1.png");loadimage(img_bullet + 1, "images/bullet2.png");//加载敌机图片loadimage(&img_enemy[0][0], "images/enemy1.png");loadimage(&img_enemy[0][1], "images/enemy1.png");loadimage(&img_enemy[1][0], "images/enemy2.png");loadimage(&img_enemy[1][1], "images/enemy2.png");
}//绘制桌面
void draw_graph()
{//绘制函数putimage(0, 0, &img_bk);
}
//绘制飞机
void draw_gamer(Plane* gamer)
{//通过初始化的飞机结构,确定其位置和加载哪一张图片drawImg(gamer->x, gamer->y, &img_gamer[gamer->frame]);gamer->frame = (++(gamer->frame)) % 2;
}
//绘制子弹
void draw_bullet(Bullet* bullet)
{for (int i = 0; i < BULLET_NUM; i++){//发射绘制第一张if (bullet[i].isDie){drawImg(bullet[i].x, bullet[i].y, img_bullet + 0);}//碰到敌人或者墙壁我们绘制第二张(后续我们会更改)if(bullet[i].y == 0){drawImg(bullet[i].x, bullet[i].y, img_bullet + 1);}}
}绘制敌机
//void enemyDraw(Plane* enemy) {
//	// 绘制敌机
//	for (int num = 0; num < ENEMY_NUM; num++) {
//		if (!enemy[num].isDie) {
//			if (enemy[num].type == BIG) {
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][0]);
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][1]);
//			}
//			else if (enemy[num].type == SMALL) {
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][0]);
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][1]);
//			}
//		}
//	}
//}// 创建敌机
void createEnemy(Plane* enemy) {for (int i = 0; i < ENEMY_NUM; i++){if (!enemy[i].isDie){//创建随机坐标enemy[i].x = rand() % (getwidth() - 60);enemy[i].y = 0;enemyHP(i, enemy);enemy[i].isDie = true;//生成敌机break;}}
}
// 绘制敌机
void enemyDraw(Plane* enemy) {//static int count = 0;for (int num = 0; num < ENEMY_NUM; num++){if (enemy[num].isDie){//printf("%d ", count++);if (enemy[num].type == BIG){drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][0]);drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][1]);}else{drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][0]);drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][1]);}}}}
//void enemyDraw(Plane* enemy) {
//	//绘制敌机
//	for (int num = 0; num < ENEMY_NUM; num++)
//	{
//		if (enemy[num].isDie)
//		{
//			if (enemy[num].type == BIG)
//			{
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][0]);
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[1][1]);
//			}
//			else
//			{
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][0]);
//				drawImg(enemy[num].x, enemy[num].y, &img_enemy[0][1]);
//			}
//		}
//	}
//
//}
//绘制函数
void draw(Plane* gamer,Bullet* bullet, Plane* enemy)
{draw_graph();draw_gamer(gamer);draw_bullet(bullet);enemyDraw(enemy);}void init_gamer(Plane* gamer,int x,int y)
{gamer->x = x;gamer->y = y;gamer->isDie = false;gamer->frame = 0;gamer->hp = 100;gamer->width = 102;gamer->height = 126;
}void init_bullet(Bullet* bullet)
{for (int i = 0; i < BULLET_NUM; i++){bullet[i].isDie = false;//bullet[i].x = x;//bullet[i].y = y;//我们这里通过按下空格键再去绘制它,所以在这里我们并不需要去更新坐标}
}void init_enemy(Plane* enemy)
{for (int i = 0; i < ENEMY_NUM; i++){enemy[i].isDie = false;}
}
//初始化函数
void init(Plane* gamer, Bullet* bullet, Plane* enemy)
{//我们在初始化的时候就可以将,资源加载Resource();//初始化飞机init_gamer(gamer, ((getwidth() - img_gamer->getwidth()) / 2),(getheight() - img_gamer->getheight()));//(gamer->x) / 2, gamer->y + img_bullet->getheight()init_bullet(bullet);init_enemy(enemy);
}void timerFunction(int frameRate) {clock_t startTime, currentTime;long elapsed;// 计算每一帧的毫秒数int ms_per_frame = 1000 / frameRate;// 获取初始时间startTime = clock();while (1) {// 获取当前时间currentTime = clock();// 计算已经过去的时间(以毫秒为单位)elapsed = (currentTime - startTime) * 1000;// 如果已经过去的时间超过了下一帧的时间间隔,则输出一帧if (elapsed >= ms_per_frame) {// 更新初始时间startTime = currentTime;// 暂停一段时间,使得每秒输出指定的帧率Sleep(1); // 暂停 1 毫秒break;}}
}void createBullet(Plane* gamer, Bullet* bullet)
{//循环遍历找到可用的子弹,进行发射for (int i = 0; i < BULLET_NUM; i++){if (!bullet[i].isDie){bullet[i].isDie = true;bullet[i].x = gamer->x + img_gamer->getwidth() / 2;bullet[i].y = gamer->y;break;}}
}
//移动飞机,发射子弹
void palygamer(Plane* gamer, Bullet* bullet)
{if (GetAsyncKeyState(VK_UP) && gamer->y > 0){gamer->y -= MOVE;}if (GetAsyncKeyState(VK_DOWN) && gamer->y + img_gamer->getheight() < getheight()){gamer->y += MOVE;}if (GetAsyncKeyState(VK_LEFT) && gamer->x + img_gamer->getwidth() / 2 > 0){gamer->x -= MOVE;}if (GetAsyncKeyState(VK_RIGHT) && gamer->x + img_gamer->getwidth() / 2 < getwidth()){gamer->x += MOVE;}if (GetAsyncKeyState(VK_SPACE) && timer.hasElapsed(100, 1)){createBullet(gamer, bullet);}
}
//子弹移动
void movebullet(Bullet* bullet)
{for (int i = 0; i < BULLET_NUM; i++){if (bullet[i].isDie){bullet[i].y -= MOVE;//如果子弹跑出窗口,则置为falseif (bullet[i].y < 0){bullet[i].isDie = false;}}}
}//void moveEnemy(Plane* enemy)
//{
//	for (int i = 0; i < ENEMY_NUM; i++)
//	{
//		if (enemy[i].isDie)
//		{
//			enemy[i].y += 3;
//			if (enemy[i].y > getheight() || enemy[i].hp <= 0)
//			{
//				enemy[i].isDie = false;
//			}
//		}
//	}
//}
// 移动敌机
void moveEnemy(Plane* enemy) {for (int i = 0; i < ENEMY_NUM; i++){if (enemy[i].isDie){enemy[i].y += 3;if (enemy[i].y > getheight()){enemy[i].isDie = false;}}}
}
//碰撞检测
void checkCollision(Plane* gamer,Plane* enemy, Bullet* bullet)
{for (int i = 0; i < ENEMY_NUM; i++){if (!enemy[i].isDie)continue;for (int j = 0; j < BULLET_NUM; j++){if (!bullet[j].isDie)continue;if (bullet[j].x > enemy[i].x &&bullet[j].x < enemy[i].x + enemy[i].width &&bullet[j].y > enemy[i].y &&bullet[j].y < enemy[i].y + enemy[i].height){bullet[j].isDie = false;enemy[i].hp--;}}if (enemy[i].hp <= 0) enemy[i].isDie = false;}for (int i = 0; i < ENEMY_NUM; i++){if (gamer->x + gamer->width >= enemy[i].x &&gamer->x <= enemy[i].x + enemy[i].width &&gamer->y <= enemy[i].y + enemy[i].height &&gamer->y + gamer->height >= enemy[i].y){//可以给一个窗口,问是否需要重来,或者可以加一些关机操作,都是没有问题的,根据你们想要的逻辑去改代码即可exit(1);}}}//void checkCollision(Plane* enemy, Bullet* bullet) {
//	if (!enemy || !bullet) {
//		// 参数验证失败,输出错误信息并返回
//		printf("Error: Invalid parameters in checkCollision function.\n");
//		return;
//	}
//
//	for (int j = 0; j < ENEMY_NUM; j++) {
//		if (!enemy[j].isDie) {
//			continue;
//		}
//		for (int i = 0; i < BULLET_NUM; i++) {
//			if (!bullet[i].isDie) {
//				continue;
//			}
//
//			if (bullet[i].x > enemy[j].x && bullet[i].x < (enemy[j].x + enemy[j].width)
//				&& bullet[i].y > enemy[j].y && (bullet[i].y < enemy[j].y + enemy[j].height)) {
//				bullet[i].isDie = false;
//				enemy[j].hp--;
//			}
//		}
//	}
//}//void updateEnemyStatus(Plane* enemy) {
//	if (!enemy) {
//		// 参数验证失败,输出错误信息并返回
//		printf("Error: Invalid parameters in updateEnemyStatus function.\n");
//		return;
//	}
//
//	for (int j = 0; j < ENEMY_NUM; j++) {
//		if (enemy[j].hp == 0) {
//			enemy[j].isDie = false;
//		}
//	}
//}//更新数据
void Updata(Plane* gamer,Bullet* bullet, Plane* enemy)
{//玩家移动palygamer(gamer, bullet);//子弹移动movebullet(bullet);//创建敌机if (timer.hasElapsed(1000, 1)){//printf("6");createEnemy(enemy);}//移动敌机moveEnemy(enemy);//子弹打到飞机checkCollision(gamer,enemy, bullet);
}

13,tools.cpp

#include "aircraft.h"//把像素的颜色拆解出来 ARGB
typedef struct _ARGB {byte a;byte r;byte g;byte b;
}ARGB;
//把颜色拆分
ARGB color2Argb(DWORD c) {ARGB res;res.r = (byte)c;res.g = (byte)(c >> 8);res.b = (byte)(c >> 16);res.a = (byte)(c >> 24);return res;
}
DWORD argb2Color(ARGB c) {DWORD t = RGB(c.r, c.g, c.b);return ((DWORD)c.a) << 24 | t;
}
//把色彩图转成黑白图
void toGray(IMAGE* src) {DWORD* psrc = GetImageBuffer(src);for (int i = 0; i < src->getwidth() * src->getheight(); i++) {//获取每一个像素点的颜色值ARGB t = color2Argb(psrc[i]);//灰度图,求三个或者四个颜色值的均值byte arv = (t.r + t.g + t.b) / 3;ARGB res = { t.a,arv,arv,arv };psrc[i] = argb2Color(res);}
}
/*
* @png透明贴图
*/
void drawImg(int x, int y, IMAGE* src) {// 变量初始化DWORD* pwin = GetImageBuffer();//窗口缓冲区指针DWORD* psrc = GetImageBuffer(src);//图片缓冲区指针int win_w = getwidth();//窗口宽高int win_h = getheight();int src_w = src->getwidth();//图片宽高int src_h = src->getheight();//计算贴图的实际长宽int real_w = (x + src_w > win_w) ? win_w - x : src_w;//处理超出右边界int real_h = (y + src_h > win_h) ? win_h - y : src_h;//处理超出右边界if (x < 0) {//处理超出左边界psrc += -x;real_w -= -x;x = 0;}if (y < 0) {//处理超出右边界psrc += (src_w * -y);real_h -= -y;y = 0;}//修正贴图起始位置pwin += (win_w * y + x);//实现透明贴图for (int iy = 0; iy < real_h; iy++) {for (int ix = 0; ix < real_w; ix++) {byte a = (byte)(psrc[ix] >> 24);//计算透明通道的值[0,256] 0为完全透明 255完全不透明if (a > 100) {pwin[ix] = psrc[ix];}}//换到下一行pwin += win_w;psrc += src_w;}
}

14,main.cpp


#include "aircraft.h"int main()
{Plane gamer;Bullet bullet[BULLET_NUM];Plane enemy[ENEMY_NUM];//创建窗口函数initgraph(graph_width, graph_height, 1);//获取当前时间init(&gamer, bullet, enemy);BeginBatchDraw();//双缓冲while (1){draw(&gamer, bullet, enemy);FlushBatchDraw();//立即刷新缓冲区Updata(&gamer, bullet, enemy);timerFunction(60);//checkCollision(enemy, bullet);}EndBatchDraw();//结束缓冲return 0;
}

15,每期一问

上期答案:
#define MY_OFFSETOF(s, m) ((size_t)(&(((s*)0)->m)))

本期问题:

环形链表的约瑟夫问题_牛客题霸_牛客网

下期再见!


http://www.ppmy.cn/devtools/6533.html

相关文章

Excel文件解析(Java)

一、概述 在应用程序的开发过程中&#xff0c;经常需要使用 Excel文件来进行数据的导入或导出。所以&#xff0c;在通过Java语言实现此类需求的时候&#xff0c;往往会面临着Excel文件的解析(导入&#xff09;或生成&#xff08;导出)。 在Java技术生态圈中&#xff0c…

JavaScript之分时函数、分时间段渲染页面、提高用户体验、参数归一化、高阶函数、分段、appendChild、requestIdleCallback

MENU 前言效果图html原始写法优化方式一(参数归一化)优化方式二(当浏览器不支持requestIdleCallback方法的时候)优化方式三(判断环境) 前言 当前需要向页面插入十万个div元素&#xff0c;如果使用普通的渲染方式&#xff0c;会造成延迟。这时候就需要通过分时函数来实现渲染了。…

数字化校园在职校教育中的价值和前景

在当今信息化浪潮中&#xff0c;职校教育正以前所未有的速度迈入智慧校园时代。数字化校园以其强大的功能和广泛的适用性&#xff0c;正在深刻地改变职校的教学模式、管理模式以及学生的学习方式&#xff0c;助力职校教育实现高质量、高效率、个性化的转型&#xff0c;如何利用…

【R语言】动画图:散点图

绘制成如下的散点图&#xff1a; 如果数据量大&#xff0c;有多个年份&#xff0c;就会生成多张图&#xff0c;例如&#xff1a; 具体代码如下&#xff1a; library(gapminder)#加载 gapminder 包&#xff0c;其中包含了从 1952 年至 2007 年各个国家的 GDP、预期寿命和人口数据…

Java工具类:封装Okhttp实现:Get、Post、上传/下载文件、Stream响应、代理ip

不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 一、介绍 本文代码是引入Okhttp_v4.11.0,在这个基础上进行二次封装使调用方更加容易,只关注业务,而无需处理各种请求相关的重复性操作,类似文件类型请求体封装或者Form表单构造及body传参等一系列处理工具代码包括但不限…

排序算法-快速排序

快速排序 快速排序原理 快速排序&#xff08;Quick Sort&#xff09;是一种基于分治思想的排序算法&#xff0c;通过选择一个基准值&#xff0c;将数组分为两个子数组&#xff0c;一个子数组中的元素都比基准值小&#xff0c;另一个子数组中的元素都比基准值大&#xff0c;然…

009 springboot整合mybatis-plus 增删改查 ajax 登录退出accessToken

文章目录 ConfigRegistCenter.javaMybatisplusConfig.javaCustomerController.javaReceiveAddressJsonController.javaCustomer.javaLoginCustomer.javaReceiveAddress.javaJwtInterceptor.javaCustomerMapper.javaReceiveAddressMapper.javaCustomerServiceImpl.javaReceiveAd…

HTML5 <video> 标签属性、API 方法、事件、自定义样式详解与实用示例

HTML5 <video> 标签为网页内嵌视频提供了强大且便捷的功能。以下是对 <video> 标签的主要属性、API 方法、事件、自定义样式及其使用示例的详细介绍&#xff1a; 一、属性 1. src 定义&#xff1a;指定视频文件的 URL。示例&#xff1a;<video src"my_v…

R语言:相关性可视化绘图+进阶散点图矩阵、高密度散点图、六边形封箱图、气泡图

相关性可视化绘图 以相关系数表示的二元关系&#xff1a;通过散点图和散点图矩阵进行可视化 &#xff08;1&#xff09;散点图&#xff1a;plot(x, y) 其中&#xff0c;x和y是数值型向量&#xff0c;代表着图形中的(x,y)点 &#xff08;2&#xff09;进阶散点图&#xff1a;…

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(1)——场景故事介绍

生成NPC为交互应用程序创建逼真的人类行为模拟。在这项工作中&#xff0c;我们通过将二十五个NPC放置在一个沙盒环境中&#xff08;类似于The Sims&#xff0c;模拟人生&#xff09;&#xff0c;展示了生成NPC的能力。用户可以观察和干预NPC的日常计划、分享新闻、建立关系以及…

(四)SQL面试题(连续登录、近N日留存)学习简要笔记 #CDA学习打卡

目录 一. 连续登录N天的用户数量 1&#xff09;举例题目 2&#xff09;分析思路 3&#xff09;解题步骤 &#xff08;a&#xff09;Step1&#xff1a;选择12月的记录&#xff0c;并根据用户ID和登录日期先去重 &#xff08;b&#xff09;Step2&#xff1a;创建辅助列a_rk…

实习学习内容-Lua语法

Lua是一种轻量级的脚本语言&#xff0c;以其简单、灵活和高效的特点被广泛应用于嵌入式系统、游戏开发和服务器端编程中。Lua语言的设计目标是为了嵌入应用程序中&#xff0c;提供灵活的扩展和定制功能。下面&#xff0c;我将简要介绍Lua的基本语法和特点。 基本语法 变量和类…

【element】实现基于Element UI的日期范围选择:限制选定日期在30天内

实现基于Element UI的日期范围选择&#xff1a;限制选定日期在30天内 在Web应用开发过程中&#xff0c;我们经常遇到需要用户在一个特定日期范围内做出选择的场景。使用Element UI的el-date-picker组件&#xff0c;我们可以轻松实现这一功能。本文将指导你如何设置el-date-pic…

智能商品计划系统如何提升鞋服零售品牌的竞争力

国内鞋服零售企业经过多年的发展&#xff0c;已经形成了众多知名品牌&#xff0c;然而近年来一些企业频频受到库存问题的困扰&#xff0c;这一问题不仅影响了品牌商自身&#xff0c;也给长期合作的经销商带来了困扰。订货会制度在初期曾经有效地解决了盲目生产的问题&#xff0…

从日志读取关键数据,按照相关日期进行数据分析

分析靠近后向挡墙的距离 import os import re import sys import matplotlib.pyplot as plt from datetime import datetimedef process_distance_data(file_path):distances []timestamps []try:with open(file_path, r, encodingutf-8, errorsignore) as file:for line in…

免费使用ChatGPT 4.0 和 文心一言 4.0

前言 今天给大家分享如何免费使用ChatGPT4.0 和 文心一言 4.0&#xff0c;废话就不多说了&#xff0c;我们直接入正题。 ChatGPT 4.0 先来看看如何免费使用ChatGPT 4.0 进入Coze登录 https://www.coze.com 选择大圣-GPT-4 文心一言 4.0 通过文心智能体平台&#xff0c;就…

Spring Cloud Gateway集成聚合型Spring Boot API发布组件knife4j,增强Swagger

大家都知道&#xff0c;在前后端分离开发的时代&#xff0c;前后端接口对接是一项必不可少的工作。 可是&#xff0c;作为后端开发&#xff0c;怎么和前端更好的配合&#xff0c;才能让自己不心累、脑累&#xff0c;直接扔给前端一个后端开放api接口文档或者页面&#xff0c;让…

ROS分布式通讯配置

4WD 必读&#xff1a;分布式通讯是相对于用虚拟机来连接小车上主机来说&#xff0c;如果是 4WD 笔记本无主 机用户&#xff0c;不存在分布式通讯一说。 1.4WD 用户单笔记设置一&#xff0c;连接底盘和雷达还有摄像头。 因为虚拟机带宽问题&#xff0c;无法保证摄像头正常运行。…

LeetCode 383.赎金信(模拟,for(char c : 容器)的使用)

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&#…

GlobalRouting - FastRoute布线算法运行流程(二)

文章目录 1. 运行步骤 FT::run 1. 运行步骤 首先生成2D的布线&#xff0c;然后进行层分配以及生成3D的布线&#xff0c;最后计算结果并返回。具体流程如下&#xff1a; 读取查找表flut, POST9.dat, POWV9.dat使用查找表生成RSMT&#xff0c;将多pin线网拆分为2pin线网进行第…