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

OpenHarmony游戏应用程序-实现的一个手柄游戏

介绍

本篇Codelab是基于TS扩展的声明式开发范式编程语言,以及OpenHarmony的分布式能力实现的一个手柄游戏。

说明: 本示例涉及使用系统接口,需要手动替换Full SDK才能编译通过。

完成本篇Codelab需要两台开发板,一台开发板作为游戏端,一台开发板作为手柄端,实现如下功能:

  • 游戏端呈现飞机移动、发射子弹等效果。
  • 游戏端分布式拉起手柄端FA。
  • 手柄端与游戏端建立连接,发送指令给游戏端,比如移动飞机,发射子弹和释放技能等。

最终效果图如下:

搭建OpenHarmony环境

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。

      以3.1版本为例:

2.搭建烧录环境。

  • 完成DevEco Device Tool的安装
  • 完成RK3568开发板的烧录

3.搭建开发环境。

  • 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
  • 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”),选择JS或者eTS语言开发。
  • 工程创建完成后,选择使用真机进行调测。

分布式组网

本章节以系统自带的音乐播放器为例(具体以实际的应用为准),介绍如何完成两台设备的分布式组网。

  1. 硬件准备:准备两台烧录相同的版本系统的RK3568开发板A、B。
  2. 开发板A、B连接同一个WiFi网络。

打开设置-->WLAN-->点击右侧WiFi开关-->点击目标WiFi并输入密码。

3.将设备A,B设置为互相信任的设备。

  • 找到系统应用“音乐”。

  • 设备A打开音乐,点击左下角流转按钮,弹出列表框,在列表中会展示远端设备的id。

  • 选择远端设备B的id,另一台开发板(设备B)会弹出验证的选项框。

  • 设备B点击允许,设备B将会弹出随机PIN码,将设备B的PIN码输入到设备A的PIN码填入框中。

  1. 配网完毕。

代码结构解读

  • HandleEtsOpenHarmony
  • GameEtsOpenHarmony

本篇Codelab只对核心代码进行讲解,首先介绍一下整个工程的代码结构:

└── HandleGameApplication│── GameEtsOpenHarmony│  └── HandleEtsOpenHarmony

其中HandleEtsOpenHarmony为手柄端工程代码,GameEtsOpenHarmony为游戏端工程代码。

HandleEtsOpenHarmony

  • MainAbility:存放应用主页面。
    • pages/index.ets:应用主页面。
    • common/images:存放图片资源的目录。
  • ServiceAbility:存放ServiceAbility相关文件。
    • service.ts:service服务,用于跨设备连接后通讯。

GameEtsOpenHarmony

  • MainAbility:存放应用主页面。
    • pages/index.ets:应用主页面。
    • common/images:存放图片资源。
  • model:存放获取组网内的设备列表相关文件。
    • RemoteDeviceModel.ets:获取组网内的设备列表。
    • GameElement.ets:游戏端界面元素的实体类,用于封装子弹、飞机等元素的属性。
  • ServiceAbility:存放ServiceAbility相关文件。
    • service.ts:service服务,用于跨设备连接后通讯。

实现手柄端功能

  1. 实现布局和样式。

手柄端有两个功能:向游戏端发送指令和实时获取游戏端得分数据。界面上有三个功能组件:蓝色图形组件用于控制游戏端飞机移动方向,黄色图形组件用于发射子弹,绿色图形组件用于释放技能,效果图如下:

主要代码如下:

@Entry
@Component
struct Index {
...build() {Stack() {...Text('score:' + this.score)...Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.SpaceBetween }) {Stack() {Image('/common/images/bigcircle.png').width(300).height(300)Image('/common/images/smallcircle.png').width(140).height(140).position({ x: this.smallPosX, y: this.smallPosY }) // 30+75-35}...Row() {Image('/common/images/a.png').width(160).height(160).margin({ right: 20, bottom: 80 })Image('/common/images/b.png').width(200).height(200)}.alignItems(VerticalAlign.Bottom)...}}
}

2.实现摇杆功能。

给摇杆(蓝色小圆图形)添加TouchEvent,动态改变摇杆position属性使摇杆跟随手指移动,主要代码如下:

onTouchEvent(event: TouchEvent) {switch (event.type) {case TouchType.Down:this.startX = event.touches[0].screenX;this.startY = event.touches[0].screenY;break;case TouchType.Move:this.curX = event.touches[0].screenX;this.curY = event.touches[0].screenY;this.getSmallCurrentPos(this.curX - this.smallR - 60, this.curY - this.smallR - 60)angle = Math.round(this.calculateAngle());break;default:break;}
}

3.计算摇杆偏移角度。

主要代码如下:

calculateAngle() {var angle = 0var degree = Math.atan(this.getDisAbsY() / this.getDisAbsX()) * 180 / Math.PIvar quadrant = this.quadrant();switch (quadrant) {case this.QUADRANT_1:// 向右上移动angle = degree;break;case this.QUADRANT_2:// 向左上移动angle = 180 - degree;break;case this.QUADRANT_3:// 向左下移动angle = -180 + degree;break;case this.QUADRANT_4:// 向右下移动angle = -degree;break;default:angle = 0;break;}return angle;
}

4.连接游戏端Service。

当手柄端被游戏端拉起时,获取游戏端传递的数据:游戏端deviceId和分数score。然后通过deviceId连接游戏端Service,主要代码如下:

aboutToAppear() {// 当被拉起时,通过want传递的参数同步对端界面UIawait featureAbility.getWant((error, want) => {// 远端被拉起后,连接游戏端的serviceif (want.parameters.deviceId) {let remoteDeviceId = want.parameters.deviceIdconnectRemoteService(remoteDeviceId)}});
}async function connectRemoteService(deviceId) {
...await featureAbility.connectAbility({'deviceId': deviceId,'bundleName': "com.huawei.cookbook",'abilityName': "com.huawei.cookbook.ServiceAbility",},{onConnect: onConnectCallback,onDisconnect: onDisconnectCallback,onFailed: onFailedCallback,},);
}

5.通过RPC发送数据到游戏端。

连接游戏端Service之后,摇杆角度angle和操作类型actionType(1为发射子弹,2为释放技能)发送给游戏端,主要代码如下:

async function sendMessageToRemoteService() {
...let option = new rpc.MessageOption();let data = new rpc.MessageParcel();let reply = new rpc.MessageParcel();data.writeInt(actionType);data.writeInt(angle);await mRemote.sendRequest(1, data, reply, option);
}

实现游戏端功能

  1. 实现布局和样式。

游戏界面主要由玩家飞机、敌机、子弹和道具(降落伞)等组成,由于敌机和子弹都是多个的,所以使用ForEach来实现,主要代码如下:

@Entry
@Component
struct Index {build() {Stack() {... ForEach(this.bullets, item => {Image(item.imgSrc).width(item.imgWidth).height(item.imgHeight).position({ x: item.positionX, y: item.positionY })}, item => item.timestamp.toString())ForEach(this.enemyPlanes, item => {Image(item.imgSrc).width(item.imgWidth).height(item.imgHeight).position({ x: item.positionX, y: item.positionY })}, item => item.timestamp.toString())Image('/common/images/planeOne.png').width(this.planeSize).height(this.planeSize).position({ x: this.planePosX, y: this.planePosY }).onTouch((event: TouchEvent) => {this.onTouchEvent(event)})Image('/common/images/props.png').width(this.propsSize).height(this.propsSize).position({ x: this.propsPosX, y: this.propsPosY })...}.height('100%').width('100%')}
}

2.实现游戏端元素动画效果。

飞机、子弹和道具等元素的移动是通过动态改变Image的position属性来实现的。使用定时器setInterval每隔16ms重新设置界面元素position属性的值,主要实现代码如下:

 startGame() {var that = thissetInterval(function () {   // 每60*16ms创建一个敌机if (that.num % 60 == 0) {that.createEnemyPlane()}// 移动子弹var bulletsTemp: GameElement[] = []for (var i = 0; i < that.bullets.length; i++) {var bullet = that.bullets[i]bullet.positionY -= 8// 当子弹移除屏幕外的时候,释放掉if (bullet.positionY > 0) {bulletsTemp.push(bullet)}}that.bullets = bulletsTemp// 移动飞机var enemyPlanesTemp: GameElement[] = []for (var j = 0; j < that.enemyPlanes.length; j++) {var enemyPlane = that.enemyPlanes[j]enemyPlane.positionY += 6// 当飞机移除屏幕外的时候,释放掉if (enemyPlane.positionY < that.screenHeight) {enemyPlanesTemp.push(enemyPlane)}}that.enemyPlanes = enemyPlanesTemp// 每隔 500*16ms显示降落伞if (that.num % 500 == 0) {that.getPropsFlag = truethat.propsPosY = -that.propsSizethat.propsPosX = Math.round((Math.random() * (that.screenWidth - that.propsSize)))}// 刷新道具位置if (that.propsPosY < that.screenHeight) {that.propsPosY += 6}that.checkCollision()}, 16);}

3.判断元素是否发生碰撞。

在setInterval中改变元素位置的时候同时检测元素之间是否发生碰撞,子弹和敌机发生碰撞则分数值改变(摧毁小飞机加50分,摧毁大飞机加100分),玩家飞机和道具发生碰撞则道具加1,主要实现代码如下:

 checkCollision() {...for (var i = 0; i < this.enemyPlanes.length; i++) {var enemy = this.enemyPlanes[i];for (var j = 0; j < this.bullets.length; j++) {var bullet = this.bullets[j];var inside = this.isInside(bullet, enemy);// 发生碰撞if (inside) {enemy.imgSrc = '/common/images/boom.png'if (enemy.flag == 1) {this.score += 50sendMessageToRemoteService(that.score)} else if (enemy.flag == 2) {this.score += 100sendMessageToRemoteService(that.score)}// 清除子弹this.enemyPlanes.splice(i, 1);i--;enemy.flag = 3// 清除被子弹打中敌机that.bullets.splice(j, 1);j--;}}}// 飞机和降落伞是否发生碰撞var isGetProps = this.isInside(myPlane, props);if (isGetProps && this.getPropsFlag) {this.getPropsFlag = falsethis.bombNum++this.propsPosY = 2000}}

4.获取设备列表。

点击界面右上角的“电脑”图标,调用registerDeviceListCallback()发现设备列表,并弹出设备列表选择框DeviceListDialog ,选择设备后拉起远端FA。DeviceListDialog 主要代码如下:

@CustomDialog
export struct DeviceListDialog {controller: CustomDialogControllerbuild() {Column() {Text("选择设备").fontWeight(FontWeight.Bold).fontSize(20).margin({ top: 20, bottom: 10 })List() {ForEach(deviceList, item => {ListItem() {Stack() {Text(item).fontSize(12).margin({ top: 10 })}.onClick(() => {startRemoteAbility(item)this.controller.close();}).padding({ left: 30, right: 30 })}}, item => item.toString())}.height("30%").align(Alignment.TopStart)
...}}
}

5.拉起手柄端FA。

点击设备列表获取远程设备id后,拉起手柄端FA,代码如下:

function startRemoteAbility(deviceId) {var params = {deviceId: localDeviceId}var wantValue = {bundleName: 'com.huawei.cookbook',abilityName: 'com.huawei.cookbook.MainAbility',deviceId: deviceId,parameters: params};featureAbility.startAbility({want: wantValue}).then((data) => {console.info('[game] featureAbility.startAbility finished, localDeviceId=' + localDeviceId + '----deviceId:' + deviceId);// 拉起远端后,连接远端serviceconnectRemoteService(deviceId)});
}

6.连接手柄端Service。

拉起手柄端FA后,连接手柄端Service,代码如下:

async function connectRemoteService(deviceId) {// 连接成功的回调async function onConnectCallback(element, remote) {mRemote = remote;}
...if (remoteDeviceModel.deviceList.length === 0) {return;}await featureAbility.connectAbility({'deviceId': deviceId,'bundleName': "com.huawei.cookbook",'abilityName': "com.huawei.cookbook.ServiceAbility",},{onConnect: onConnectCallback,onDisconnect: onDisconnectCallback,onFailed: onFailedCallback,},);
}

7.通过RPC发送数据到手柄端。

通过RPC将游戏分数发送给手柄端,主要代码如下:

async function sendMessageToRemoteService(score) {console.log('[game]connectRemoteService sendMessageToRemoteService:')if (mRemote == null) {return;}let option = new rpc.MessageOption();let data = new rpc.MessageParcel();let reply = new rpc.MessageParcel();data.writeInt(score);await mRemote.sendRequest(1, data, reply, option);
}

8.Service发布公共事件。

通过Service接收手柄端数据,然后使用CommonEvent模块将数据发送给FA,主要代码如下:

class GameServiceAbilityStub extends rpc.RemoteObject {
...onRemoteRequest(code, data, reply, option) {console.log('[game]Service onRemoteRequest');var publishCallBack;if (code === 1) {// 读取手柄端发送的数据let actionType = data.readInt();let angle = data.readInt();reply.writeInt(100);var params = {actionType: actionType,angle: angle,}var options = {code: 1,data: 'init data',isOrdered: true,bundleName: 'com.huawei.cookbook',parameters: params}publishCallBack = function () {}// 发布公共事件commonEvent.publish("publish_action", options, publishCallBack);} return true;}
}

9.FA订阅公共事件。

订阅公共事件,接收从Service发送的公共事件数据,actionType 为操作类型(1表示发送子弹指令,2表示释放技能指令),angle 为飞机移动的角度。接收到数据后执行手柄端发送的指令:移动玩家飞机、发射子弹和释放技能摧毁所有敌机,主要代码如下:

subscribeEvent() {
...// 订阅公共事件回调function SubscribeCallBack(err, data) {let msgData = data.data;let code = data.code;
...// 处理接收到的数据datathat.actionType = data.parameters.actionType;that.angle = data.parameters.angle;if (that.actionType == 1) {that.createBullet()}if (that.actionType == 2) {if (that.bombNum > 0) {that.bombNum--that.destroyAllEnemy()}}if (that.angle != 0) {that.movePlaneByHandle()}}//创建订阅者回调function CreateSubscriberCallBack(err, data) {subscriber = data;//订阅公共事件commonEvent.subscribe(subscriber, SubscribeCallBack);}//创建订阅者commonEvent.createSubscriber(subscribeInfo, CreateSubscriberCallBack);
}

恭喜您

通过本篇Codelab,您可以学到:

如何跨设备拉起远程FA。

如何连接远程Service。

使用RPC实现本地FA和远程Servcice通信。

通过CommonEvent发布与订阅实现Service和FA之间通信。

为了帮助大家更深入有效的学习到鸿蒙开发知识点,小编特意给大家准备了一份全套最新版的HarmonyOS NEXT学习资源,获取完整版方式请点击→《HarmonyOS教学视频

HarmonyOS教学视频

鸿蒙语法ArkTS、TypeScript、ArkUI等.....视频教程

鸿蒙生态应用开发白皮书V2.0PDF:

获取白皮书完整版方式请点击→《鸿蒙生态应用开发白皮书V2.0PDF》

鸿蒙 (Harmony OS)开发学习手册

一、入门必看

  1. 应用开发导读(ArkTS)
  2. ……

二、HarmonyOS 概念

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全
  5. ........

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

四、开发基础知识

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

五、基于ArkTS 开发

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙 (Harmony OS)开发学习手册

相关文章:

OpenHarmony游戏应用程序-实现的一个手柄游戏

介绍 本篇Codelab是基于TS扩展的声明式开发范式编程语言&#xff0c;以及OpenHarmony的分布式能力实现的一个手柄游戏。 说明&#xff1a; 本示例涉及使用系统接口&#xff0c;需要手动替换Full SDK才能编译通过。 完成本篇Codelab需要两台开发板&#xff0c;一台开发板作为游…...

Redis+Lua脚本+SpringAOP实现接口限流

提到限流,常规情况,可以通过spring-cloud-starter-alibaba-sentinel 或者 resilience4j-ratelimiter 组件完成,但是如果不借助现有组件让我们自己开发一套限流工作应该如何应对呢? 本次我们通过Redis + Lua 脚本来实现一个限流组件。 首先创建项目:redis-limit <?xml…...

【wpf应用8】如何让WPF Grid控件根据屏幕尺寸自动调整

简介&#xff1a; 在Windows Presentation Foundation&#xff08;WPF&#xff09;中&#xff0c;Grid控件是一个强大的布局工具&#xff0c;它允许开发者创建复杂且响应迅速的用户界面。在不同的设备和屏幕尺寸上保持良好的布局一致性是一个挑战。本文将介绍如何让Grid控件根据…...

掌握ChatGPT:如何用AI撰写高质量论文

ChatGPT无限次数:点击直达 掌握ChatGPT&#xff1a;如何用AI撰写高质量论文 在当今信息爆炸的时代&#xff0c;人们不仅需要大量信息&#xff0c;还需要这些信息的整理与创新。人工智能技术正是我们在这个信息化时代最强大的助手之一。ChatGPT是一款基于大型神经网络的语言生成…...

平衡隐私与效率,Partisia Blockchain 解锁数字安全新时代

原文&#xff1a;https://cointelegraph.com/news/exploring-multiparty-computations-role-in-the-future-of-blockchain-privacy&#xff1b; https://medium.com/partisia-blockchain/unlocking-tomorrow-outlook-for-mpc-in-2024-and-beyond-cb170e3ec567 编译&#xff1…...

【JavaScript】NPM常用指令指南

河水清清弯又长 姑娘水边浣霓裳 清风卷过白云旁 飞鸟载来春花香 河水清清弯又长 姑娘水边浣霓裳 清风卷过白云旁 朝霞换夕阳 重逢是梦乡 春潮悠悠送波浪 石桥湾下小舟荡 此去经年谁如常 难得人间笑一场 春潮悠悠送波浪 石桥湾下小舟荡 此去经年谁如常 故人心头上 地久天又长 …...

k8s-多容器Pod、容器保护策略、宽限期、最大生命周期、嵌入式脚本、多容器Pod、资源监控工具

资源对象文件 一、模板与帮助信息 1、资源对象文件优势 命令无法实现高级复杂的功能某些资源对象使用命令无法创建方便管理、保存、追溯历史 2、如何生成资源对象模板 资源对象 Pod 模板使用 run 生成 [rootmaster ~]# kubectl run myweb --imagemyos:nginx --dry-runcli…...

机器学习——线性回归(头歌实训)

头歌机器学习实训代码、答案&#xff0c;如果能够帮到您&#xff0c;希望可以点个赞&#xff01;&#xff01;&#xff01; 如果有问题可以csdn私聊或评论&#xff01;&#xff01;&#xff01;感谢您的支持 目录 第1关&#xff1a;简单线性回归与多元线性回归 第2关&#…...

Echarts 利用多X轴实现未来15天天气预报

Echarts 利用多X轴实现未来15天天气预报 UI 设计图 Echarts 实现效果 代码实现 代码分解 echarts 图表上下均显示数据 通过设置 grid.top 和 grid.bottom 设置白天和夜间天气展示区域 grid: {top: 36%,bottom: 36%,left: 5%,right: 5%}, 天气图标的设置 由于 axisLabel 的…...

[数据结构初阶]二叉树

各位读者老爷好&#xff0c;鼠鼠我现在浅浅介绍一些关于二叉树的知识点&#xff0c;在各位老爷茶余饭后的闲暇时光不妨看看&#xff0c;鼠鼠很希望得到各位老爷的指正捏&#xff01; 开始介绍之前&#xff0c;给各位老爷看一张风景照&#xff0c;有读者老爷知道在哪里吗&#x…...

matlab和stm32的安装环境。能要求与时俱进吗,en.stm32cubeprg-win64_v2-6-0.zip下载太慢了

STM32CubeMX 6.4.0 Download STM32CubeProgrammer 2.6.0 Download 版本都更新到6.10了&#xff0c;matlab还需要6.4&#xff0c;除了st.com其他地方都没有下载的,com.cn也没有。曹 还需要那么多固件安装。matlab要求制定固件位置&#xff0c;然后从cubemx中也指定…...

Opencv面试题

1、OpenCV中cv::Mat的深拷贝和浅拷贝问题? 深拷贝&#xff1a;分配新内存的同时拷贝数据&#xff0c;当被赋值的容器被修改时&#xff0c;原始容器数据不会改变。浅拷贝&#xff1a;仅拷贝数据&#xff0c;当被赋值容器修改时&#xff0c;原始容器数据也会做同样改变。 深拷贝…...

Python连接MariaDB数据库

2024软件测试面试刷题&#xff0c;这个小程序&#xff08;永久刷题&#xff09;&#xff0c;靠它快速找到工作了&#xff01;&#xff08;刷题APP的天花板&#xff09;【持续更新最新版】-CSDN博客 Python连接MariaDB数据库 一、安装mariadb库 pip install mariadb 二、连接…...

基于python+vue的ITS 信息平台的设计与实现flask-django-nodejs-php

伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对系统进行规范而严格是十分有必要的&#xff0c;所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套信息平台&#xff0c;帮助交通局进行信息共享、交通信…...

MediatR 框架使用FluentValidation对Comand/Query进行自动拦截验证

简介 目录 简介 1. MediatR项目框架 2. 实现步骤 步骤 1&#xff1a;编写管道行为 1. query 查询的管道 2. command命令的管道 步骤 2&#xff1a;注册验证器和管道行为 步骤 3&#xff1a;定义命令类 步骤 4&#xff1a;定义处理程序 步骤 5&#xff1a;编写命令验证器…...

TS + Vue3 elementUI 表格列表中如何方便的标识不同类型的内容,颜色区分 enum

TS Vue3 elementUI 表格列表中如何方便的标识不同类型的内容&#xff0c;颜色区分 enum 本文内容为 TypeScript 一、基础知识 在展示列表的时候&#xff0c;列表中的某个数据可能是一个类别&#xff0c;比如&#xff1a; enum EnumOrderStatus{"未受理" 1,"…...

从零开始一步一步掌握大语言模型---(2-什么是Token?)

了解自然语言处理或者听说过大语言模型的同学都听过&#xff0c;token。一般来说&#xff0c;它代表的是语言中不可再分的最小单元。我们人类的语言不仅有文字&#xff0c;还有语音。针对文字、语音来说&#xff0c;它们都各自有不同的划分token的方法。本节将尽可能详细的介绍…...

使用专属浏览器在国内直连GPT教程

Wildcard官方推特发文说他们最近推出了一款专门为访问OpenAI设计的浏览器。 根据官方消息&#xff0c;这是一款专门为访问OpenAI优选网络设计的浏览器&#xff0c;它通过为用户提供专用的家庭网络出口&#xff0c;确保了快速、稳定的连接。 用这个浏览器的最大好处就是直接用浏…...

Wireshark 抓包工具与长ping工具pinginfoview使用,安装包

一、Wireshark使用 打开软件&#xff0c;选择以太网 1、时间设置时间显示格式 这个时间戳不易直观&#xff0c;我们修改 2、抓包使用的命令 1&#xff09;IP地址过滤 ip.addr192.168.1.114 //筛选出源IP或者目的IP地址是192.168.1.114的全部数据包。 ip.sr…...

分享Pandas 数据分析实战课程

分享Pandas 数据分析实战课程&#xff0c;3 小时掌握数据分析核心技能。 链接&#xff1a;https://pan.baidu.com/s/1Ikk3I1dfoFO0id3EBZJdGg?pwd4y83 提取码&#xff1a;4y83 链接&#xff1a;https://pan.quark.cn/s/fa2acd7513f4 提取码&#xff1a;yWu7...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...