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

STM32学习笔记十八:WS2812制作像素游戏屏-飞行射击游戏(8)探索游戏多样性,范围伤害模式

 前面我们的攻击手段比较单一,虽然已经分出了 EnemyT1 / EnemyT2 / EnemyT3, 但里面还是基本一样的。这回,我们尝试实现一些新的攻击方法,实现一些新的算法。

1、前面我们小飞机EnemyT1 的攻击方式是垂直向下发射子弹。

那么大飞机EnemyT2的攻击手段就更高级一些,我们让它能够瞄准玩家射击。

大飞机EnemyT2发射子弹是EnemyT2类的私有方法,想要让他能够瞄准玩家,就要知道玩家在哪里。还记得前面我们做的数据仓库么。这回用上了。

我们修改EnemyT2的createBulletObject函数:

void EnemyT2::createBulletObject(PlaneObject_t *target) {BulletObject_t *but1 = new BulletObject_t();but1->x = baseInfo.x - PlaneXYScale;but1->y = baseInfo.y + PlaneXYScale * 2;but1->visiable = 1;int sum = abs(target->x - but1->x) + abs(target->y - but1->y);but1->speedX = 300 * (target->x - but1->x) / sum;but1->speedY = 300 * (target->y - but1->y) / sum;getRainbowColor(&but1->color, 200);ListPushBack(enemyBulletList, (LTDataType) but1);
}uint8_t EnemyT2::tick(uint32_t t) {。。。if (fireTimer.tick(t)) {if (((PlaneObject_t*) DataBulk::GetInstance()->data1)->visiable)createBulletObject((PlaneObject_t*) DataBulk::GetInstance()->data1);if (((PlaneObject_t*) DataBulk::GetInstance()->data2)->visiable)createBulletObject((PlaneObject_t*) DataBulk::GetInstance()->data2);}。。。
}

注意确定子弹方向的算法:

    int sum = abs(target->x - but1->x) + abs(target->y - but1->y);

    but1->speedX = 300 * (target->x - but1->x) / sum;
    but1->speedY = 300 * (target->y - but1->y) / sum;

300是子弹速度。

简单通过相似三角形来确定方向和速度,不是很精确,但也足够用了。如果要精确的话,需要用三角函数算分速度,太复杂,没必要。

2、Boss肯定要更强大,我们要让他同时向多个方向发射散弹,同时发射一颗能追踪的导弹。

先给他发射散弹:

void EnemyT3::createBulletObject(int speedX) {PlaneObject_t *but1 = new PlaneObject_t();but1->x = baseInfo.x - PlaneXYScale * 2;but1->y = baseInfo.y + PlaneXYScale;but1->speedX = speedX;but1->speedY = 300 - abs(speedX);but1->visiable = 1;but1->color = 0xe01000;ListPushBack(enemyBulletList, (LTDataType) but1);
}uint8_t EnemyT3::tick(uint32_t t) {animationStoryBoard->tick(t);if (fireTimer.tick(t)) {createBulletObject(-120);createBulletObject(-70);createBulletObject(-30);createBulletObject(0);createBulletObject(30);createBulletObject(70);createBulletObject(120);}for (ListNode *node = animationList->next; node != animationList; node =node->next) {if (((Animation*) node->data)->isValid) {((Animation*) node->data)->tick(t);}}return 0;
}

追踪导弹不是直线运动,所以要单独一个链表 enemyRocketList,单独的算法:

class BulletManager {
public:BulletManager();virtual ~BulletManager();uint8_t tick(uint32_t t);void init();uint8_t show(void);ListNode *player1BulletList;ListNode *player2BulletList;ListNode *enemyBulletList;ListNode *enemyRocketList;
private:void tickOnce(ListNode *list, uint32_t t);void showOnce(ListNode *list);void destoryOnce(ListNode *list);void tickRocket(uint32_t t);
};
void BulletManager::tickRocket(uint32_t t) {for (ListNode *cur = enemyRocketList->next; cur != enemyRocketList; cur =cur->next) {PlaneObject_t *bullet = (PlaneObject_t*) (cur->data);PlaneObject_t *target =bullet->tag == 1 ? Player1BaseInfo : Player2BaseInfo;int sum = abs(target->x - bullet->x) + abs(target->y - bullet->y);bullet->speedX = 50 * (target->x - bullet->x) / sum;bullet->speedY = 50 * (target->y - bullet->y) / sum;bullet->x += bullet->speedX * t;bullet->y += bullet->speedY * t;}
}uint8_t BulletManager::tick(uint32_t t) {tickOnce(player1BulletList, t);tickOnce(player2BulletList, t);tickOnce(enemyBulletList, t);tickRocket(t);return 0;
}

然后发射导弹:

void EnemyT3::createRocketObject(int target) {PlaneObject_t *but1 = new PlaneObject_t();but1->x = baseInfo.x - PlaneXYScale * 2;but1->y = baseInfo.y + PlaneXYScale;but1->visiable = 1;but1->color = 0xe01000;but1->tag = target;ListPushBack(EnemyRocketList, (LTDataType) but1);
}
uint8_t EnemyT3::tick(uint32_t t) {animationStoryBoard->tick(t);if (fireTimer.tick(t)) {
。。。if (Player1BaseInfo->visiable)createRocketObject(1);if (Player2BaseInfo->visiable)createRocketObject(2);}
。。。return 0;
}

补充,为了方法,把数据的地址都在DataBulk里面管起来。

void Plane::init() {backGroundStar.init();bulletManager.init();player1.init(1);player1.bulletList = bulletManager.player1BulletList;enemyManager.init();DataBulk::GetInstance()->data1 = (intptr_t) &player1.baseInfo;DataBulk::GetInstance()->data2 = (intptr_t) &player2.baseInfo;DataBulk::GetInstance()->data3 = (intptr_t) bulletManager.player1BulletList;DataBulk::GetInstance()->data4 = (intptr_t) bulletManager.player2BulletList;DataBulk::GetInstance()->data5 = (intptr_t) bulletManager.enemyBulletList;DataBulk::GetInstance()->data6 = (intptr_t) bulletManager.enemyRocketList;}

添加宏:

PlaneDef.h

#define Player1BaseInfo ((PlaneObject_t*)DataBulk::GetInstance()->data1)
#define Player2BaseInfo ((PlaneObject_t*)DataBulk::GetInstance()->data2)
#define Player1BulletList ((ListNode*)DataBulk::GetInstance()->data3)
#define Player2BulletList ((ListNode*)DataBulk::GetInstance()->data4)
#define EnemyBulletList ((ListNode*)DataBulk::GetInstance()->data5)
#define EnemyRocketList ((ListNode*)DataBulk::GetInstance()->data6)

最后,给导弹就上生命周期:

typedef struct {int x;int y;int color;int speedX;int speedY;uint8_t visiable = 0;uint8_t width;uint8_t height;int life = 0x7fffffff;int tag;
} PlaneObject_t;
void BulletManager::tickRocket(uint32_t t) {for (ListNode *cur = enemyRocketList->next; cur != enemyRocketList; cur =cur->next) {PlaneObject_t *bullet = (PlaneObject_t*) (cur->data);bullet->life -= t;if (bullet->life < 0) {bullet->visiable = 0;continue;}PlaneObject_t *target =bullet->tag == 1 ? Player1BaseInfo : Player2BaseInfo;int sum = abs(target->x - bullet->x) + abs(target->y - bullet->y);bullet->speedX = 50 * (target->x - bullet->x) / sum;bullet->speedY = 50 * (target->y - bullet->y) / sum;bullet->x += bullet->speedX * t;bullet->y += bullet->speedY * t;}
}

三种敌机都有了足够的差异化了,不同的形状,不同的飞行方式,不同的攻击方式,甚至击毁效果都不一样。不枉我们把它们区分为3个不同的类。

下面再来考虑玩家的攻击方式。

原来只有子弹,我们给他加上炸弹和激光。

子弹击中就没有了,而炸弹和激光属于范围攻击模式,其伤害是持续性的,而且与时间有关系。先做炸弹。

设定炸弹效果为半径=7的圆,碰撞检测销毁敌方子弹,对敌机持续造成 time * 1 的伤害。每玩家只有一个在生效。

先在像素屏驱动里面补充一个单片机上常用的画圆方法,Bresenham算法。具体原理不再赘述,可自行网上搜索。

不用三角函数的函数就是好函数。


void ws2812_Fill_Circle(uint16_t x0, uint16_t y0, uint8_t r, uint32_t color) {int x = 0, y = r, d;d = 3 - 2 * r;while (x <= y) {ws2812_fill(x0 - x, y0 - y, x * 2, 1, (color & 0xff0000) >> 16,(color & 0xff00) >> 8, color & 0xff);ws2812_fill(x0 - x, y0 + y - 1, x * 2, 1, (color & 0xff0000) >> 16,(color & 0xff00) >> 8, color & 0xff);ws2812_fill(x0 - y, y0 - x, 1, x * 2, (color & 0xff0000) >> 16,(color & 0xff00) >> 8, color & 0xff);ws2812_fill(x0 + y - 1, y0 - x, 1, x * 2, (color & 0xff0000) >> 16,(color & 0xff00) >> 8, color & 0xff);if (d < 0) {d = d + 4 * x + 6;} else {d = d + 4 * (x - y) + 10;y--;}x++;}ws2812_fill(x0 - y, y0 - y, y * 2, y * 2, (color & 0xff0000) >> 16,(color & 0xff00) >> 8, color & 0xff);
}

1、定义一个结构 EffectObject_t 保存效果信息:

typedef struct {int type;int x;int y;int life = 0x7fffffff;
} EffectObject_t;

2、在玩家类里面加上爆炸效果 effectObject :

class PlanePlayer {
public:PlanePlayer();~PlanePlayer();void init(uint8_t id);uint8_t tick(uint32_t t, uint8_t b1);uint8_t show(void);uint8_t hitDetect(int x, int y, int damage);uint8_t hitEffectDetect(int x, int y, int r);
。。。EffectObject_t *effectObject = NULL;int HP;
private:
。。。
};

3、在plane.cpp里面加上 爆炸效果的碰撞检测遍历:

void Plane::checkEffectCollision(uint32_t t, PlanePlayer *player) {if (player->effectObject == NULL)return;for (ListNode *enemy = enemyManager.enemyList->next;enemy != enemyManager.enemyList; enemy = enemy->next) {EnemyBase *ene = (EnemyBase*) enemy->data;if (ene->explodeState)continue;uint8_t res = player->hitEffectDetect(ene->baseInfo.x, ene->baseInfo.y,(ene->baseInfo.width + ene->baseInfo.height) / 3);if (res) {ene->HP -= res * t;ene->hurt();}}for (ListNode *enemyBul = bulletManager.enemyBulletList->next;enemyBul != bulletManager.enemyBulletList; enemyBul =enemyBul->next) {PlaneObject_t *bul = (PlaneObject_t*) enemyBul->data;uint8_t res = player->hitEffectDetect(bul->x, bul->y, 1);if (res) {bul->visiable = 0;}}for (ListNode *enemyBul = bulletManager.enemyRocketList->next;enemyBul != bulletManager.enemyRocketList; enemyBul =enemyBul->next) {PlaneObject_t *bul = (PlaneObject_t*) enemyBul->data;uint8_t res = player->hitEffectDetect(bul->x, bul->y, 1);if (res) {bul->visiable = 0;}}
}

注意,敌机、敌方子弹、敌方导弹都有可能被爆炸摧毁。

4、在玩家类里加上碰撞检测:

uint8_t PlanePlayer::hitEffectDetect(int x, int y, int r) {switch (effectObject->type) {case 1: {int a = (x - effectObject->x) / 100;int b = (y - effectObject->y) / 100;int c = (r + 10) * 100;return (a * a + b * b < c * c) ? 1 : 0;}}return 0;
}

5、显示玩家的,顺手显示爆炸效果:

uint8_t PlanePlayer::show(void) {if (effectObject != NULL) {ws2812_Fill_Circle(effectObject->x / PlaneXYScale,effectObject->y / PlaneXYScale, 10, 0x801000);}for (uint8_t y = 0; y < 5; y++) {for (uint8_t x = 0; x < 5; x++) {if (PlaneSharp[y][x])ws2812_pixel(x + baseInfo.x / PlaneXYScale - 2,y + baseInfo.y / PlaneXYScale - 2,(baseInfo.color >> 16) & 0xff,(baseInfo.color >> 8) & 0xff, baseInfo.color & 0xff);}}return 0;
}

TODO:其实爆炸小时不应该和显示玩家纠结在一起。如果有多种特殊武器,还是单独写个函数显示为好。

 好了,对于激光来说,激光要跟随玩家移动。增加激光特效,只要增加碰撞检测和显示两部分就行了。

激光的碰撞检测:

uint8_t PlanePlayer::hitEffectDetect(int x, int y, int r) {switch (effectObject->type) {case 1: {int a = (x - effectObject->x) / 100;int b = (y - effectObject->y) / 100;int c = (r + 10) * 100;return (a * a + b * b < c * c) ? 1 : 0;}case 2:return (x / PlaneXYScale == baseInfo.x / PlaneXYScale) ? 1 : 0;}return 0;
}

 激光的显示:

uint8_t PlanePlayer::show(void) {if (effectObject != NULL) {if (effectObject->type == 1) {ws2812_Fill_Circle(effectObject->x / PlaneXYScale,effectObject->y / PlaneXYScale, 10, 0x801000);} else {ws2812_fill(baseInfo.x / PlaneXYScale, 0, 1,baseInfo.y / PlaneXYScale, 0, 100, 200);}}for (uint8_t y = 0; y < 5; y++) {for (uint8_t x = 0; x < 5; x++) {if (PlaneSharp[y][x])ws2812_pixel(x + baseInfo.x / PlaneXYScale - 2,y + baseInfo.y / PlaneXYScale - 2,(baseInfo.color >> 16) & 0xff,(baseInfo.color >> 8) & 0xff, baseInfo.color & 0xff);}}return 0;
}

 比较一下,加一个激光特效,只要两行代码。0到1不容易,1到2快的飞起。

 最后,在玩家操作里面加上炸弹和激光:

uint8_t PlanePlayer::tick(uint32_t t, uint8_t b1) {
。。。if (effectObject == NULL) {if (b1 & KEY_BUTTON_D) {effectObject = new EffectObject_t();effectObject->x = baseInfo.x;effectObject->y =(baseInfo.y > 25 * PlaneXYScale) ?baseInfo.y - 25 * PlaneXYScale : 0;effectObject->type = 1;effectObject->life = 4000;} else if (b1 & KEY_BUTTON_A) {effectObject = new EffectObject_t();effectObject->x = baseInfo.x;effectObject->y = baseInfo.y;effectObject->type = 2;effectObject->life = 4000;}} else {effectObject->life -= t;if (effectObject->life < 0) {delete effectObject;effectObject = NULL;}}。。。return 0;
}

看看效果: 

STM32学习笔记十七:WS2812制作像素游戏屏-飞行射击

STM32学习笔记十九:WS2812制作像素游戏屏-飞行射击游戏(9)探索道具系统

相关文章:

STM32学习笔记十八:WS2812制作像素游戏屏-飞行射击游戏(8)探索游戏多样性,范围伤害模式

前面我们的攻击手段比较单一&#xff0c;虽然已经分出了 EnemyT1 / EnemyT2 / EnemyT3&#xff0c; 但里面还是基本一样的。这回&#xff0c;我们尝试实现一些新的攻击方法&#xff0c;实现一些新的算法。 1、前面我们小飞机EnemyT1 的攻击方式是垂直向下发射子弹。 那么大飞机…...

C#获取windows系统资源使用情况

1.前言 之前有一篇博客介绍如何获取Linux服务器上的资源使用情况《Java 获取服务器资源&#xff08;内存、负载、磁盘容量&#xff09;》&#xff0c;这里介绍如何通过C#获取Window系统的资源使用。 2.获取服务器资源 2.1.内存 [DllImport("kernel32.dll")][retu…...

PE解释器之PE文件结构

PE文件是由许许多多的结构体组成的&#xff0c;程序在运行时就会通过这些结构快速定位到PE文件的各种资源&#xff0c;其结构大致如图所示&#xff0c;从上到下依次是Dos头、Nt头、节表、节区和调试信息(可选)。其中Dos头、Nt头和节表在本文中统称为PE文件头(因为SizeOfHeaders…...

Android—— MIPI屏调试

一、实现步骤 1、在kernel/arch/arm/boot/dts/lcd-box.dtsi文件中打开&dsi0节点&#xff0c;关闭其他显示面板接口&#xff08;&edp_panel、&lvds_panel&#xff09; --- a/kernel/arch/arm/boot/dts/lcd-box.dtsib/kernel/arch/arm/boot/dts/lcd-box.dtsi-5,14 …...

BLE协议—协议栈基础

BLE协议—协议栈基础 BLE协议栈基础通用访问配置文件层&#xff08;Generic Access Profile&#xff0c;GAP&#xff09;GAP角色设备配置模式和规程安全模式广播和扫描 BLE协议栈基础 蓝牙BLE协议栈包含三部分&#xff1a;主机、主机接口层和控制器。 主机&#xff1a;逻辑链路…...

yolov8知识蒸馏代码详解:支持logit和feature-based蒸馏

文章目录 1. 知识蒸馏理论2. yolov8 蒸馏代码应用2.1 环境配置2.2 训练模型(1) 训练教师模型(2) 训练学生模型baseline(3) 蒸馏训练3. 知识蒸馏代码详解3.1 蒸馏参数设置3.2 蒸馏损失代码讲解3.2.1 Feature based loss3.2.1 Logit loss3.3 获取蒸馏的feature map及channels...

03-微服务-Ribbon负载均衡

Ribbon负载均衡 1.1.负载均衡原理 SpringCloud底层其实是利用了一个名为Ribbon的组件&#xff0c;来实现负载均衡功能的。 那么我们发出的请求明明是http://userservice/user/1&#xff0c;怎么变成了http://localhost:8081的呢&#xff1f; 1.2.源码跟踪 为什么我们只输入…...

2023新年总结与展望

2023年总结 对Spring Cloud微服务更加熟悉&#xff0c;对consul、kafka、gateway的熟悉和掌握更近一步对docker和虚拟化部署更加熟悉对PostgreSQL数据库和JPA更加熟悉对clickhouse数据库和大数据分析更加熟悉对netty和socket网络通信更加熟悉 2024年flag 继续深入研究和学习…...

论文阅读——SG-Former

SG-Former: Self-guided Transformer with Evolving Token Reallocation 1. Introduction 方法的核心是利用显著性图&#xff0c;根据每个区域的显著性重新分配tokens。显著性图是通过混合规模的自我关注来估计的&#xff0c;并在训练过程中自我进化。直观地说&#xff0c;我们…...

常用环境部署(十三)——GitLab整体备份及迁移

一、GitLab备份 注意&#xff1a;由于我的GitLab是docker安装的&#xff0c;所以我的操作都是在容器内操作的&#xff0c;大家如果不是用docker安装的则直接执行命令就行。 1、Docker安装GitLab 链接&#xff1a;常用环境部署(八)——Docker安装GitLab-CSDN博客 2、GitLab备…...

海外数据中心代理与住宅代理:优缺点全面对比

数据中心代理和住宅代理是为了匿名而开发的&#xff0c;通过替换网站眼中您自己的 IP 地址。然而&#xff0c;它们在价格、功能、性能或最佳用例方面存在一些差异。那么&#xff0c;这些代理类型到底有什么相似点和不同点呢&#xff1f; 一、什么是数据中心代理&#xff1f; 1…...

springboot实现OCR

1、引入依赖 <dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>4.5.4</version> </dependency> 2、config Configuration public class TessOcrConfiguration {Beanpublic …...

【Scala 】注解

在 Scala 中&#xff0c;你可以使用注解来为类、方法或字段添加元数据&#xff0c;影响它们的行为。Scala 的注解使用与 Java 类似&#xff0c;但是 Scala 也支持自定义注解。 文章目录 注解的常见使用方法自定义注解 注解的常见使用方法 以下是一些 Scala 中常见的注解以及它…...

数通基础知识总结

1. 基础概念 1.1. 通信基本原理 通信基本原理涉及信息的生成、编码、传输和解码的过程。在实际应用中&#xff0c;例如电话通信&#xff0c;信息通过话筒转换成模拟信号&#xff0c;经过传输线路传递到接收端&#xff0c;再由耳机解码还原为可理解的信息。 1.2. 信道和信号 …...

机器学习深度学习面试笔记

机器学习&深度学习面试笔记 机器学习Q. 在线性回归中&#xff0c;如果自变量之间存在多重共线性&#xff0c;会导致什么问题&#xff1f;如何检测和处理多重共线性&#xff1f;Q. 什么是岭回归(Ridge Regression)和Lasso回归(Lasso Regression)&#xff1f;它们与普通线性回…...

安卓和Android是两种不同的操作系统?

实际上&#xff0c;安卓和Android并不是同一种操作系统&#xff01; Android是由Google开发并维护更新的一款操作系统&#xff0c;目前仅能运行在Pixel手机上。 Google Pixel 与 iPhone手机&#xff1a;哪个更好&#xff1f;Google Pixel 与 Apple iPhone哪个手机才是性价比最…...

Java学习——设计模式——结构型模式2

文章目录 结构型模式装饰者模式桥接模式外观模式组合模式享元模式 结构型模式 结构型模式主要涉及如何组合各种对象以便获得更好、更灵活的结构。虽然面向对象的继承机制提供了最基本的子类扩展父类的功能&#xff0c;但结构型模式不仅仅简单地使用继承&#xff0c;而更多地通过…...

什么是Maven ??? (以及关于依赖,中央仓库,国内源)

文章目录 什么是 Maven创建第一个 Maven 项目依赖管理Maven 的仓库Maven 如何设置国内源 什么是 Maven Maven &#xff1a;用于构建和管理任何基于java的项目的工具。**说白了就是管理 Java项目 的工具。**我们希望我们已经创建了一些东西&#xff0c;可以使Java开发人员的日常…...

c++期末考题笔试来咯

最后一道大题题目再现 写一个person类&#xff0c;有姓名&#xff0c;性别&#xff0c;年龄。然后在此基础上派生出教师类和学生类。教师类增加了以下数据&#xff1a;工号&#xff0c;职称&#xff0c;工资。学生类增加了以下数据成员&#xff1a;学号&#xff0c;专业&#…...

目标检测篇:如何根据xml标注文件生成类别classes的json文件

1. 介绍 之前在做目标检测任务的时候&#xff0c;发现很多的数据集仅有数据(只有图片标注的xml文件)&#xff0c;没有关于类别的json文件&#xff0c;为了以后方便使用&#xff0c;这里记录一下 一般来说&#xff0c;yolo标注的数据集&#xff0c;只有第一个是数字类别&#x…...

spring见解2基于注解的IOC配置

3.基于注解的IOC配置 学习基于注解的IOC配置&#xff0c;大家脑海里首先得有一个认知&#xff0c;即注解配置和xml配置要实现的功能都是一样的&#xff0c;都是要降低程序间的耦合。只是配置的形式不一样。 3.1.创建工程 3.1.1.pom.xml <?xml version"1.0" en…...

Uncaught TypeError: Cannot read property ‘snj‘ of null

项目场景&#xff1a; 项目相关背景&#xff1a; 调试项目时&#xff0c;控制台出现红色报错信息 问题描述 问题&#xff1a; 调试项目时&#xff0c;控制台出现如下所示的报错信息&#xff1a; Uncaught TypeError: Cannot read property snj of nullat T.Inj.Ya [as Inj…...

Jenkins基础教程

目录 第一章、快速了解Jenkins1.1&#xff09;Jenkins中一些概念介绍1.2&#xff09;Jenkins和maven用途上的区别1.3&#xff09;为什么使用Jenkins1.4&#xff09;学习过程中的疑问 第二章、安装Jenkins2.1&#xff09;安装之前的准备2.2&#xff09;Windows中Jenkins下载安装…...

嵌入式C语言--WatchDog最全概念

嵌入式C语言–WatchDog最全概念 嵌入式C语言--WatchDog最全概念 嵌入式C语言--WatchDog最全概念一. 什么是Watchdog1&#xff09;什么是“被狗咬”2&#xff09;什么是喂狗 二. 基本思想三. 作用四. 监视目标1) 监视一个进程2&#xff09;监视一个操作系统 五. 系统初始化时关闭…...

数据结构【树篇】(二)

数据结构【树篇】(二&#xff09; 文章目录 数据结构【树篇】(二&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f; 目录树(一)、树的存储(二)、树和森林的遍历——并查集(三)、并查集的优化 结语 前言 为什么突然想学算法了&#xf…...

2024上海城博会|上海国际城市与建筑博览会-官 网

2024上海城博会|上海国际城市与建筑博览会 时间&#xff1a;2024年10月30日-11月1日 地点&#xff1a;上海世博展览馆 主办单位&#xff1a;联合国人居署 上海市住房和城乡建设管理委员会 协办单位&#xff1a;上海世界城市日事务协调中心 展会介绍 上海国际城市与建筑博览…...

Dockerfile - 基于 SpringBoot 项目自定义镜像(项目上线全过程)

目录 一、Dockerfile 自定义项目镜像 1.1、创建 SpringBoot 项目并编写 1.2、打包项目&#xff08;jar&#xff09; 1.3、编写 Dockerfile 文件&#xff0c;构建镜像 1.4、运行镜像并测试 一、Dockerfile 自定义项目镜像 1.1、创建 SpringBoot 项目并编写 a&#xff09;简…...

论文查重降重写成大白话可以吗

大家好&#xff0c;今天来聊聊论文查重降重写成大白话可以吗&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 论文查重降重&#xff1a;用大白话解析 一、引言 写论文是每个…...

【WPF.NET开发】WPF中的命令

本文内容 什么是命令WPF 中的简单命令示例WPF 命令中的四个主要概念命令库创建自定义命令 命令是 Windows Presentation Foundation (WPF) 中的一种输入机制&#xff0c;与设备输入相比&#xff0c;它提供的输入处理更侧重于语义级别。 示例命令如许多应用程序均具有的“复制…...

怎么将epub转换成txt文件?

怎么将epub转换成txt文件&#xff1f;在当前时代&#xff0c;各种各样的电子书是很多人都喜欢接触并阅读的&#xff0c;但很少有人知道电子书格式的不同&#xff0c;其中就包括epub和txt格式&#xff0c;这两种格式虽然都可以展示文本但能达到的效果完全不一样&#xff0c;在某…...

哪个地方旅游网站做的比较好/上海优化公司

ssh-keygen.exe cat ~/.ssh/id_rsa.pub 转载于:https://www.cnblogs.com/chentailin/p/11136191.html...

台湾做网站/百度指数在线查询

转载于:https://www.cnblogs.com/zhaoqingqing/p/3407390.html...

wordpress去掉google字体/武汉seo创造者

同学毕业设计做了一个Online Judge&#xff0c;应该是河海第一个自主的OJ雏形了&#xff0c;放在github上&#xff0c;我也凑了个热闹。 久闻git大名&#xff0c;一直没用过&#xff0c;昨天捣鼓了一下&#xff0c;几个比较不错的资料如下&#xff1a; 关于git: http://prog…...

哪些网站是用asp.net开发的/市场调研怎么写

场景 今天运用到了锁&#xff0c;记录一下lock和Synchronized的区别。 Synchronized synchronized 是 Java 中的关键字&#xff0c;是一种同步锁。它修饰的对象有以下几种&#xff1a; 修饰一个代码块&#xff0c;被修饰的代码块称为同步语句块&#xff0c;其作用的范围是大…...

网站模版好建设吗/seo专业优化方法

zabbix 使用进阶&#xff08;五&#xff09;概述&#xff1a;本章内容具体如下&#xff1a;自定义key不带参数&#xff1b;自定义key可传递参数&#xff1b;在agent端自定义可传递参数的key&#xff0c;来获取nginx的状态信息&#xff1a;基于SNMP监控的创建和和使用&#xff1…...

做ppt时网站怎么设计/无锡网站制作优化

Spring框架对于Java后端程序员来说再熟悉不过了&#xff0c;以前只知道它用的反射实现的&#xff0c;但了解之后才知道有很多巧妙的设计在里面。如果不看Spring的源码&#xff0c;你将会失去一次和大师学习的机会&#xff1a;它的代码规范&#xff0c;设计思想很值得学习。我们…...