网站建设与管理教程视频教程,网站开发技术和工具,太原站扩建,驻马店怎么建设自己的网站介绍
本篇Codelab是基于TS扩展的声明式开发范式编程语言#xff0c;以及OpenHarmony的分布式能力实现的一个手柄游戏。 说明#xff1a; 本示例涉及使用系统接口#xff0c;需要手动替换Full SDK才能编译通过。 完成本篇Codelab需要两台开发板#xff0c;一台开发板作为游…介绍
本篇Codelab是基于TS扩展的声明式开发范式编程语言以及OpenHarmony的分布式能力实现的一个手柄游戏。 说明 本示例涉及使用系统接口需要手动替换Full SDK才能编译通过。 完成本篇Codelab需要两台开发板一台开发板作为游戏端一台开发板作为手柄端实现如下功能
游戏端呈现飞机移动、发射子弹等效果。游戏端分布式拉起手柄端FA。手柄端与游戏端建立连接发送指令给游戏端比如移动飞机发射子弹和释放技能等。
最终效果图如下 搭建OpenHarmony环境
完成本篇Codelab我们首先要完成开发环境的搭建本示例以RK3568开发板为例参照以下步骤进行
获取OpenHarmony系统版本标准系统解决方案二进制。 以3.1版本为例 2.搭建烧录环境。
完成DevEco Device Tool的安装完成RK3568开发板的烧录
3.搭建开发环境。
开始前请参考工具准备完成DevEco Studio的安装和开发环境配置。开发环境配置完成后请参考使用工程向导创建工程模板选择“Empty Ability”选择JS或者eTS语言开发。工程创建完成后选择使用真机进行调测。
分布式组网
本章节以系统自带的音乐播放器为例具体以实际的应用为准介绍如何完成两台设备的分布式组网。
硬件准备准备两台烧录相同的版本系统的RK3568开发板A、B。开发板A、B连接同一个WiFi网络。
打开设置--WLAN--点击右侧WiFi开关--点击目标WiFi并输入密码。 3.将设备AB设置为互相信任的设备。
找到系统应用“音乐”。 设备A打开音乐点击左下角流转按钮弹出列表框在列表中会展示远端设备的id。 选择远端设备B的id另一台开发板设备B会弹出验证的选项框。 设备B点击允许设备B将会弹出随机PIN码将设备B的PIN码输入到设备A的PIN码填入框中。 配网完毕。
代码结构解读
HandleEtsOpenHarmonyGameEtsOpenHarmony
本篇Codelab只对核心代码进行讲解首先介绍一下整个工程的代码结构
└── HandleGameApplication│── GameEtsOpenHarmony│ └── HandleEtsOpenHarmony
其中HandleEtsOpenHarmony为手柄端工程代码GameEtsOpenHarmony为游戏端工程代码。
HandleEtsOpenHarmony MainAbility存放应用主页面。 pages/index.ets应用主页面。common/images存放图片资源的目录。ServiceAbility存放ServiceAbility相关文件。 service.tsservice服务用于跨设备连接后通讯。
GameEtsOpenHarmony MainAbility存放应用主页面。 pages/index.ets应用主页面。common/images存放图片资源。model存放获取组网内的设备列表相关文件。 RemoteDeviceModel.ets获取组网内的设备列表。GameElement.ets游戏端界面元素的实体类用于封装子弹、飞机等元素的属性。ServiceAbility存放ServiceAbility相关文件。 service.tsservice服务用于跨设备连接后通讯。
实现手柄端功能
实现布局和样式。
手柄端有两个功能向游戏端发送指令和实时获取游戏端得分数据。界面上有三个功能组件蓝色图形组件用于控制游戏端飞机移动方向黄色图形组件用于发射子弹绿色图形组件用于释放技能效果图如下 主要代码如下
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 }) // 3075-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和操作类型actionType1为发射子弹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);
}
实现游戏端功能
实现布局和样式。
游戏界面主要由玩家飞机、敌机、子弹和道具降落伞等组成由于敌机和子弹都是多个的所以使用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.pngif (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.bombNumthis.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)开发学习手册
一、入门必看
应用开发导读(ArkTS)…… 二、HarmonyOS 概念
系统定义技术架构技术特性系统安全........ 三、如何快速入门《做鸿蒙应用开发到底学习些啥》
基本概念构建第一个ArkTS应用…… 四、开发基础知识
应用基础知识配置文件应用数据管理应用安全管理应用隐私保护三方应用调用管控机制资源分类与访问学习ArkTS语言…… 五、基于ArkTS 开发
Ability开发UI开发公共事件与通知窗口管理媒体安全网络与链接电话服务数据管理后台任务(Background Task)管理设备管理设备使用信息统计DFX国际化开发折叠屏系列…… 更多了解更多鸿蒙开发的相关知识可以参考《鸿蒙 (Harmony OS)开发学习手册》