From 245a7458b9e42a36f08fcdc93af78c8cd1fce10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=98=89=E8=AF=9A?= <425765923@qq.com> Date: Wed, 8 Dec 2021 17:30:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 林嘉诚 <425765923@qq.com> --- .../src/main/ets/MainAbility/pages/game.ets | 72 ++-- FA/Entertainment/BombGame/quick_develop.md | 368 +++++++++++++----- FA/Entertainment/BombGame/readme.md | 7 +- 3 files changed, 318 insertions(+), 129 deletions(-) diff --git a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/game.ets b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/game.ets index 409089a8..50d616a6 100644 --- a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/game.ets +++ b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/game.ets @@ -13,19 +13,19 @@ * limitations under the License. */ -import {RemoteDeviceManager, RemoteDevice, RemoteDeviceStatus} from './RemoteDeviceManager' +import {RemoteDeviceManager, RemoteDevice, RemoteDeviceStatus,getBundleName} from './RemoteDeviceManager' import CommonLog from "./CommonLog" import featureAbility from '@ohos.ability.featureAbility'; import prompt from '@system.prompt'; -enum TouchType { +enum RuleType { click = "单击", doubleClick = "双击", longPress = "长按", } -const touchMode: Array = [ - TouchType.click, TouchType.doubleClick, TouchType.longPress +const touchMode: Array = [ + RuleType.click, RuleType.doubleClick, RuleType.longPress ] function checkTrustedDevice(deviceList: RemoteDevice[]): boolean { @@ -47,7 +47,7 @@ function checkTrustedDevice(deviceList: RemoteDevice[]): boolean { @Component struct Game { @State private duration: number = 3000 - @State touchText: TouchType = TouchType.click + @State ruleText: RuleType = RuleType.click @State bombIndex: number = 0 @Provide deviceList: RemoteDevice[] = [] private remoteDm: RemoteDeviceManager = new RemoteDeviceManager(this.deviceList) @@ -80,7 +80,7 @@ struct Game { Image($r("app.media.title")).objectFit(ImageFit.Contain).height(120) Column() { Text(this.duration.toString() + 'ms').fontColor(Color.White) - Text(this.touchText).fontColor(Color.White) + Text(this.ruleText).fontColor(Color.White) } } @@ -97,20 +97,23 @@ struct Game { .visibility(this.bombIndex == item ? Visibility.Visible : Visibility.Hidden) // 炸弹事件 .onClick((event) => { - this.judgeGame(TouchType.click) + // 单击 + this.judgeGame(RuleType.click) CommonLog.info("onClick") }) .gesture( GestureGroup(GestureMode.Exclusive, LongPressGesture({ repeat: false }) .onAction((event: GestureEvent) => { + // 长按 CommonLog.info("LongPress") - this.judgeGame(TouchType.longPress) + this.judgeGame(RuleType.longPress) }), TapGesture({ count: 2 }) .onAction(() => { CommonLog.info("double click") - this.judgeGame(TouchType.doubleClick) + // 双击 + this.judgeGame(RuleType.doubleClick) }) ).onCancel(() => { CommonLog.info("onCancel") @@ -140,26 +143,29 @@ struct Game { this.transferNumber = status.transferNumber } if (status && status.ongoing) { - this.startGame() + this.startGame() // 继续游戏 } else { - this.ruleDialog.open() + this.ruleDialog.open() // 弹出规则弹框 } }); - this.remoteDm.refreshRemoteDeviceList() - this.remoteDm.startDeviceDiscovery() + this.remoteDm.refreshRemoteDeviceList() // 刷新设备列表 + this.remoteDm.startDeviceDiscovery() // 开始发现设备 this.setRandomBomb() - } aboutToDisappear() { CommonLog.info('aboutToDisappear'); this.stopCountDown() - this.remoteDm.stopDeviceDiscovery() + this.remoteDm.stopDeviceDiscovery() // 注销监听 } - judgeGame(operation:TouchType) { +/** + * 判断游戏输赢 + * @param operation 点击类型 + */ + judgeGame(operation:RuleType) { this.stopCountDown() - if (operation != this.touchText) { + if (operation != this.ruleText) { this.gameFail() } else { prompt.showToast({ message: "finish" }) @@ -168,15 +174,24 @@ struct Game { } } +/** + * 随机生成点击规则 + */ randomTouchRule() { let index = Math.floor(Math.random() * 3) - this.touchText = touchMode[index] + this.ruleText = touchMode[index] } +/** + * 随机生成炸弹 + */ setRandomBomb() { this.bombIndex = Math.floor(Math.random() * 9) } +/** + * 随机获取在线设备id + */ getRandomDeviceId(): string{ let onlineDeviceList = this.deviceList.filter(item => item.status == RemoteDeviceStatus.ONLINE) let randomIndex = Math.floor(Math.random() * onlineDeviceList.length) @@ -185,11 +200,12 @@ struct Game { return deviceId } - startAbilityRandom() { - let deviceId = this.getRandomDeviceId() + async startAbilityRandom() { + let deviceId = this.getRandomDeviceId() // 随机获取设备id CommonLog.info('featureAbility.startAbility deviceId=' + deviceId); + let bundleName = await getBundleName() let wantValue = { - bundleName: 'com.sample.bombgame', + bundleName: bundleName, abilityName: 'com.sample.bombgame.MainAbility', deviceId: deviceId, parameters: { @@ -209,15 +225,16 @@ struct Game { startGame() { CommonLog.info('startGame'); - this.randomTouchRule() - this.setRandomBomb() - this.stopCountDown() + this.randomTouchRule() // 随机游戏点击规则 + this.setRandomBomb() // 随机生成炸弹位置 + this.stopCountDown() // 停止倒计时 if (this.transferNumber < 10) { this.duration = 3000 - this.transferNumber * 100 } else { this.duration = 2000 } const interval: number = 500 + // 开始倒计时 this.timer = setInterval(() => { if (this.duration <= interval) { this.duration = 0 @@ -254,6 +271,10 @@ struct Game { this.playerDialog.open() } +/** + * 邀请用户(设备认证) + * @param remoteDevice 远程设备 + */ invitePlayer(remoteDevice:RemoteDevice) { if (remoteDevice.status == RemoteDeviceStatus.ONLINE) { prompt.showToast({ message: "Already invited!" }) @@ -333,6 +354,9 @@ struct GameFailDialog { this.setBombAnimate() } +/** + * 设置游戏动画 + */ setBombAnimate() { if (!this.isPlayAnimate) { return diff --git a/FA/Entertainment/BombGame/quick_develop.md b/FA/Entertainment/BombGame/quick_develop.md index 8ce33630..80e3fd12 100644 --- a/FA/Entertainment/BombGame/quick_develop.md +++ b/FA/Entertainment/BombGame/quick_develop.md @@ -19,11 +19,11 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 效果图如上可以分为两部分 -- 顶部状态提示栏 +##### 2.1 顶部状态提示栏 - 1)首先在@entry组件入口build()中使用[Stack](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-container-stack.md)作为容器,达到图片和文字堆叠的效果; +1)首先在@entry组件入口build()中使用[Stack](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-container-stack.md)作为容器,达到图片和文字堆叠的效果; - 2)接着依次写入[Image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-image.md)和[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)包裹的两个[Text](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-text.md)组件; +2)接着依次写入[Image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-image.md)和[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)包裹的两个[Text](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-text.md)组件; ``` Stack() { @@ -37,63 +37,71 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 -- 中间游戏炸弹九宫格区域 +##### 2.2 中间游戏炸弹九宫格区域 - 1)使用[Grid](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-grid.md)网格容器来编写九宫格区域; +1)使用[Grid](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-grid.md)网格容器来编写九宫格区域; - 2)在[GridItem](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-griditem.md)中[Stack](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-container-stack.md)容器依次添加方块背景图片和炸弹图片; +2)在[GridItem](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-griditem.md)中[Stack](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-container-stack.md)容器依次添加方块背景图片和炸弹图片; - 3)在visibility属性中用bombIndex变量值来决定炸弹显示的位置; +3)在visibility属性中用bombIndex变量值来决定炸弹显示的位置; - 4)通过onClick点击事件和[GestureGroup](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-combined-gestures.md#%E4%BA%8B%E4%BB%B6)组合手势加入单击、双击和长按的监听事件; +4)通过onClick点击事件和[GestureGroup](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-combined-gestures.md#%E4%BA%8B%E4%BB%B6)组合手势加入单击、双击和长按的监听事件; ``` Stack() { - Image($r("app.media.background")).objectFit(ImageFit.Contain) - Grid() { - ForEach(this.grid, (item) => { - GridItem() { - Stack() { - Image($r("app.media.squares")).objectFit(ImageFit.Contain) - Image($r("app.media.bomb")) - .width('50%') - .objectFit(ImageFit.Contain) - .visibility(this.bombIndex == item ? Visibility.Visible : Visibility.Hidden) - // 炸弹点击事件 - .onClick((event) => { - this.judgeGame(touchType.click) - }) - .gesture( - GestureGroup(GestureMode.Exclusive, - LongPressGesture({ repeat: false }) - .onAction((event: GestureEvent) => { - this.judgeGame(touchType.longPress) - }), - TapGesture({ count: 2 }) - .onAction(() => { - this.judgeGame(touchType.doubleClick) - }) - ) - } - }.forceRebuild(false) - }, item => item) - } - .columnsTemplate('1fr 1fr 1fr') - .rowsTemplate('1fr 1fr 1fr') - .columnsGap(10) - .rowsGap(10) - .width('90%') - .height('75%') - }.width('80%').height('70%') + Image($r("app.media.background")).objectFit(ImageFit.Contain) + Grid() { + ForEach(this.grid, (item) => { + GridItem() { + Stack() { + Image($r("app.media.squares")).objectFit(ImageFit.Contain) + Image($r("app.media.bomb")) + .width('50%') + .objectFit(ImageFit.Contain) + .visibility(this.bombIndex == item ? Visibility.Visible : Visibility.Hidden) + // 炸弹事件 + .onClick((event) => { + // 单击 + this.judgeGame(RuleType.click) + CommonLog.info("onClick") + }) + .gesture( + GestureGroup(GestureMode.Exclusive, + LongPressGesture({ repeat: false }) + .onAction((event: GestureEvent) => { + // 长按 + CommonLog.info("LongPress") + this.judgeGame(RuleType.longPress) + }), + TapGesture({ count: 2 }) + .onAction(() => { + CommonLog.info("double click") + // 双击 + this.judgeGame(RuleType.doubleClick) + }) + ).onCancel(() => { + CommonLog.info("onCancel") + })) + } + }.forceRebuild(false) + }, item => item) + } + .columnsTemplate('1fr 1fr 1fr') + .rowsTemplate('1fr 1fr 1fr') + .columnsGap(10) + .rowsGap(10) + .width('90%') + .height('75%') +}.width('80%').height('70%') ``` #### 3. 添加弹窗 -- 创建规则游戏弹窗 +##### 3.1 创建规则游戏弹窗 - 1)通过**@CustomDialog**装饰器来创建自定义弹窗,使用方式可参考 [自定义弹窗](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-methods-custom-dialog-box.md); +1)通过**@CustomDialog**装饰器来创建自定义弹窗,使用方式可参考 [自定义弹窗](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-methods-custom-dialog-box.md); - 2)规则弹窗效果如下,弹窗组成由两个[Text](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-text.md)和两个[Image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-canvas-image.md)竖向排列组成,所有我们可以在build()下使用[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)容器来包裹,组件代码如下; +2)规则弹窗效果如下,弹窗组成由两个[Text](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-basic-text.md)和两个[Image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/js-based-web-like-development-paradigm/js-components-canvas-image.md)竖向排列组成,所有我们可以在build()下使用[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)容器来包裹,组件代码如下; ![微信图片_20211124151049](resources/rule_dialog.png) @@ -103,7 +111,7 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 controller: CustomDialogController confirm: () => void invite: () => void - remoteDeviceModel: RemoteDeviceModel + @Consume deviceList: RemoteDevice[] build() { Column() { @@ -132,94 +140,250 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 ​ 3)在@entry创建CustomDialogController对象并传入弹窗所需参数,后面可通过该对象open()和close()方法进行打开和关闭弹窗; ``` +@Provide deviceList: RemoteDevice[] = [] private ruleDialog: CustomDialogController = new CustomDialogController({ builder: RuleDialog({ invite: () => this.InvitePlayer(), confirm: () => this.startGame(), - remoteDeviceModel: this.remoteDeviceModel + deviceList: this.deviceList }), autoCancel: false }) ``` -- 创建游戏失败弹窗,并添加动画效果 +##### 3.2 创建游戏失败弹窗,并添加动画效果 - ![合成 4](resources/game_fail.gif) +![合成 4](resources/game_fail.gif) - 1)编写弹窗布局:将游戏失败文本、炸弹图片和再来一局按钮图片放置于[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)容器中; +1)编写弹窗布局:将游戏失败文本、炸弹图片和再来一局按钮图片放置于[Column](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-container-column.md)容器中; - 2)用变量来控制动画起始和结束的位置:用[Flex](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-universal-attributes-flex-layout.md)容器包裹炸弹图片,并用[@State](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-component-states-state.md)装饰变量toggle,通过变量来动态修改[Flex](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-universal-attributes-flex-layout.md)的direction属性; +2)用变量来控制动画起始和结束的位置:用[Flex](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-universal-attributes-flex-layout.md)容器包裹炸弹图片,并用[@State](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-component-states-state.md)装饰变量toggle,通过变量来动态修改[Flex](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-universal-attributes-flex-layout.md)的direction属性; - ``` - @State toggle: boolean = true - private controller: CustomDialogController - private confirm: () => void - private interval = null - - build() { - Column() { - Text('游戏失败').fontSize(30).margin(20) - Flex({ - direction: this.toggle ? FlexDirection.Column : FlexDirection.ColumnReverse, - alignItems: ItemAlign.Center - }) - { - Image($r("app.media.bomb")).objectFit(ImageFit.Contain).height(80) - }.height(200) - - Image($r("app.media.btn_restart")).objectFit(ImageFit.Contain).height(120).margin(10) - .onClick(() => { - this.controller.close() - this.confirm() - }) - } - .width('80%') - .margin(50) - .backgroundColor(Color.White) - } - ``` +``` +@State toggle: boolean = true +private controller: CustomDialogController +@Consume deviceList: RemoteDevice[] +private confirm: () => void +private interval = null + +build() { + Column() { + Text('游戏失败').fontSize(30).margin(20) + Flex({ + direction: this.toggle ? FlexDirection.Column : FlexDirection.ColumnReverse, + alignItems: ItemAlign.Center + }) + { + Image($r("app.media.bomb")).objectFit(ImageFit.Contain).height(80) + }.height(200) + + Image($r("app.media.btn_restart")).objectFit(ImageFit.Contain).height(120).margin(10) + .onClick(() => { + this.controller.close() + this.confirm() + }) + } + .width('80%') + .margin(50) + .backgroundColor(Color.White) +} +``` - 3)设置动画效果:使用 [animateTo ](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-explicit-animation.md)显示动画接口炸弹位置切换时添加动画,并且设置定时器定时执行动画; +3)设置动画效果:使用 [animateTo ](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-explicit-animation.md)显示动画接口炸弹位置切换时添加动画,并且设置定时器定时执行动画; - ``` - aboutToAppear() { - this.setBombAnimate() - } - - setBombAnimate() { - let fun = () => { - this.toggle = !this.toggle; - } - this.interval = setInterval(() => { - animateTo({ duration: 1500, curve: Curve.Sharp }, fun) - }, 1600) - } - ``` +``` +aboutToAppear() { + this.setBombAnimate() +} + +setBombAnimate() { + let fun = () => { + this.toggle = !this.toggle; + } + this.interval = setInterval(() => { + animateTo({ duration: 1500, curve: Curve.Sharp }, fun) + }, 1600) +} +``` #### 4. 添加分布式流转 分布式流转需要在同一网络下通过 [DeviceManager组件](https://gitee.com/openharmony/device_manager) 进行设备间发现和认证,获取到可信设备的deviceId调用 **[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).startAbility** ,即可把应用程序流转到另一设备。 +原本分布式流转应用流程如下: + 1)创建DeviceManager实例; 2)调用实例的startDeviceDiscovery(),开始设备发现未信任设备; -3)设置设备状态监听on('deviceFound',callback),获取到未信任设备,并用discoverList变量进行维护; +3)设置设备状态监听on('deviceStateChange',callback),监听设备上下线状态; + +4)设置设备状态监听on('deviceFound',callback),监听设备发现; + +5)传入未信任设备参数,调用实例authenticateDevice方法,对设备进行PIN码认证; + +6)若是已信任设备,可通过实例的getTrustedDeviceListSync()方法来获取设备信息; -4)传入未信任设备参数,调用实例authenticateDevice方法,对设备进行PIN码认证; +7)将设备信息中的deviceId传入[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).startAbility方法,实现流转; -5)若是已信任设备,可通过实例的getTrustedDeviceListSync()方法来获取设备信息; +8)流转接收方可通过[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).getWant()获取到发送方携带的数据; -6)将设备信息中的deviceId传入[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).startAbility方法,实现流转; +9)注销设备发现监听off('deviceFound'); -7)流转接收方可通过[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).getWant()获取到发送方携带的数据; +10)注销设备状态监听off('deviceStateChange'); -**项目中将上面设备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList设备信息列表,实现分布式流转只需要在deviceList中获取deviceId,然后调用featureAbility.startAbility并携带数据,即可实现分布式流转。** +**项目中将上面设备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList设备信息列表。** ![RemoteDeviceManager](resources/RemoteDeviceManager.png) +项目实现分布式流转只需如下流程: + +##### 2.1 创建RemoteDeviceManager实例 + +声明[@Provide](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/ts-based-declarative-development-paradigm/ts-other-states-consume-provide.md)装饰的设备列表变量deviceList,用于生成设备管理实例RemoteDeviceManager。 + +``` +@Provide deviceList: RemoteDevice[] = [] +private remoteDm: RemoteDeviceManager = new RemoteDeviceManager(this.deviceList) +``` + +##### 2.2 刷新设备列表 + +在生命周期aboutToAppear中,调用刷新设备列表和开始发现设备。 + +aboutToAppear定义:函数在创建自定义组件的新实例后,在执行其**build**函数之前执行。 + +``` +aboutToAppear() { + this.remoteDm.refreshRemoteDeviceList() // 刷新设备列表 + this.remoteDm.startDeviceDiscovery() // 开始发现设备 +} +``` + +##### 2.3 设备认证 + +``` +invitePlayer(remoteDevice:RemoteDevice) { + if (remoteDevice.status == RemoteDeviceStatus.ONLINE) { + prompt.showToast({ message: "Already invited!" }) + return + } + this.remoteDm.authDevice(remoteDevice).then(() => { + prompt.showToast({ message: "Invite success! deviceName=" + remoteDevice.deviceName }) + }).catch(() => { + prompt.showToast({ message: "Invite fail!" }) + }) +} +``` + +##### 2.4 跨设备流转 + +从deviceList中获取设备列表在线的设备Id,通过featureAbility.startAbility进行流转。 + +``` +async startAbilityRandom() { + let deviceId = this.getRandomDeviceId() // 随机获取设备id + CommonLog.info('featureAbility.startAbility deviceId=' + deviceId); + let bundleName = await getBundleName() + let wantValue = { + bundleName: bundleName, + abilityName: 'com.sample.bombgame.MainAbility', + deviceId: deviceId, + parameters: { + ongoing: true, + transferNumber: this.transferNumber + 1 + } + }; + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + CommonLog.info(' featureAbility.startAbility finished, ' + JSON.stringify(data)); + featureAbility.terminateSelf((error) => { + CommonLog.info('terminateSelf finished, error=' + error); + }); + }); +} +``` + +##### 2.5 注销监听 + +在声明周期aboutToDisappear进行注销监听。 + +aboutToDisappear定义:函数在自定义组件析构消耗之前执行。 + +``` +aboutToDisappear() { + this.remoteDm.stopDeviceDiscovery() // 注销监听 +} +``` + +#### 5. 编写游戏逻辑 + +##### 5.1 开始游戏 + +``` +startGame() { + CommonLog.info('startGame'); + this.randomTouchRule() // 随机游戏点击规则 + this.setRandomBomb() // 随机生成炸弹位置 + this.stopCountDown() // 停止倒计时 + if (this.transferNumber < 10) { + this.duration = 3000 - this.transferNumber * 100 + } else { + this.duration = 2000 + } + const interval: number = 500 + // 开始倒计时 + this.timer = setInterval(() => { + if (this.duration <= interval) { + this.duration = 0 + clearInterval(this.timer) + this.timer = null + this.gameFail() + } else { + this.duration -= interval + } + }, interval) +} +``` + +##### 5.2 判断输赢 + +编写判断逻辑,用于不同的点击事件中调用。 + +``` +/** + * 判断游戏输赢 + * @param operation 点击类型 + */ +judgeGame(operation:RuleType) { + this.stopCountDown() + if (operation != this.ruleText) { + this.gameFail() + } else { + prompt.showToast({ message: "finish" }) + this.bombIndex = -1 + this.startAbilityRandom() + } +} +``` + +##### 5.3 游戏失败 + +游戏失败,弹出游戏失败弹框。 + +``` +gameFail() { + prompt.showToast({ + message: 'Game Fail' + }) + CommonLog.info('gameFail'); + this.gameFailDialog.open() +} +``` + ### 约束与限制 #### 1. 设备编译约束 diff --git a/FA/Entertainment/BombGame/readme.md b/FA/Entertainment/BombGame/readme.md index 2ef09e68..0498b031 100644 --- a/FA/Entertainment/BombGame/readme.md +++ b/FA/Entertainment/BombGame/readme.md @@ -11,6 +11,10 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 通过获取到的deviceId,传入到 [featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).startAbility方法中实现跨设备流转。 +### 相关链接 + +#### [从零开发传炸弹小游戏](quick_develop.md) + ### 快速上手 #### 1. Hi3516环境准备 @@ -49,6 +53,3 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 #### 3. 应用内点击开始游戏 -### 相关链接 - -#### [从零开发传炸弹小游戏](quick_develop.md) \ No newline at end of file -- Gitee