From caff8da6d258ad777b1add147a055107070b8745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=98=89=E8=AF=9A?= <425765923@qq.com> Date: Fri, 3 Dec 2021 12:05:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 林嘉诚 <425765923@qq.com> --- .../main/ets/MainAbility/pages/CommonLog.ets | 34 ++ .../MainAbility/pages/RemoteDeviceManager.ets | 291 ++++++++++++++++++ .../MainAbility/pages/RemoteDeviceModel.ets | 191 ------------ .../src/main/ets/MainAbility/pages/game.ets | 206 ++++++++----- .../main/resources/base/media/icon_user.png | Bin 0 -> 4028 bytes .../base/media/icon_user_unselect.png | Bin 0 -> 4360 bytes FA/Entertainment/BombGame/quick_develop.md | 6 + FA/Entertainment/BombGame/readme.md | 5 +- .../resources/RemoteDeviceManager.png | Bin 0 -> 52772 bytes FA/Entertainment/TicTacToeGame/README.md | 2 +- 10 files changed, 455 insertions(+), 280 deletions(-) create mode 100644 FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/CommonLog.ets create mode 100644 FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceManager.ets delete mode 100644 FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceModel.ets create mode 100644 FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user.png create mode 100644 FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user_unselect.png create mode 100644 FA/Entertainment/BombGame/resources/RemoteDeviceManager.png diff --git a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/CommonLog.ets b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/CommonLog.ets new file mode 100644 index 00000000..24297ac7 --- /dev/null +++ b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/CommonLog.ets @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * 日志管理类 + */ +export default class CommonLog { + static TAG: string = "BombGame" + static module: string = "Log" + + static info(log: string) { + console.info(`${CommonLog.TAG}_${CommonLog.module}_:${log}`) + } + + static error(log: string) { + console.error(`${CommonLog.TAG}_${CommonLog.module}_:${log}`) + } + + static debug(log: string) { + console.debug(`${CommonLog.TAG}_${CommonLog.module}_:${log}`) + } +} \ No newline at end of file diff --git a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceManager.ets b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceManager.ets new file mode 100644 index 00000000..aaf8ddcd --- /dev/null +++ b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceManager.ets @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License,Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import CommonLog from "./CommonLog" +import deviceManager from '@ohos.distributedHardware.deviceManager' +import prompt from '@system.prompt'; +import featureAbility from '@ohos.ability.featureAbility'; + +// 以下不能为空 +const APP_NAME = "BombGame" +const APP_DESCRIPTION = "BombGame" +/** + * 设备对象 + */ +export class RemoteDevice { + deviceId: string + deviceName: string + deviceType: number + status: RemoteDeviceStatus = RemoteDeviceStatus.UNTRUSTED + + constructor(deviceId: string, deviceName: string, + deviceType: number, status?: RemoteDeviceStatus) { + this.deviceId = deviceId + this.deviceName = deviceName + this.deviceType = deviceType + if (status == undefined || status == null) { + this.status = RemoteDeviceStatus.UNTRUSTED + } else { + this.status = status + } + } +} + +export enum RemoteDeviceStatus { + OFFLINE = 0, + ONLINE = 2, + UNTRUSTED = -1 +} + +export function getBundleName(): Promise { + return featureAbility.getContext().getBundleName() +} + + +/** + * 设备管理类,用于发现设备,认证设备 + */ +export class RemoteDeviceManager { + private deviceList: RemoteDevice[] = [] + private dmInstance = null + private bundleName = "" + private subscribeId:number = 1000 + + /** + * 构造函数,传入@State 或者 @Provide 装饰的设备列表数据 + * 不能对deviceList进行重新赋值,否则将不能动态更新视图 + */ + constructor(deviceList: RemoteDevice[]) { + this.deviceList = deviceList + // 使用相同的Id,若之前没有正常停止会导致第二次不能正常发现设备 + this.subscribeId = Math.floor(65536 * Math.random()); + } + + /** + * 初始化,创建deviceManager对象,返回Promise对象 + */ + async init(): Promise { + if (!this.bundleName) { + this.bundleName = await getBundleName() + CommonLog.info('getBundleName:' + this.bundleName); + } + return new Promise((resolve, reject) => { + try { + if (!this.dmInstance) { + CommonLog.info('deviceManager.createDeviceManager begin'); + deviceManager.createDeviceManager(this.bundleName, (error, value) => { + if (error) { + CommonLog.error('deviceManager.createDeviceManager failed:' + error); + reject(error) + return + } + this.dmInstance = value + CommonLog.info('deviceManager.createDeviceManager success') + resolve(this.dmInstance) + }) + } else { + CommonLog.info('dmInstance already exists') + resolve(this.dmInstance) + } + } + catch (error) { + prompt.showToast({ message: "createDeviceManager fail :" + error }) + CommonLog.error('init fail ' + JSON.stringify(error)) + reject(error) + } + }) + } + + /** + * 刷新设备列表 + */ + async refreshRemoteDeviceList() { + CommonLog.info("refreshRemoteDeviceList") + this.init().then(() => { + CommonLog.info("refreshRemoteDeviceList start") + let list = this.dmInstance.getTrustedDeviceListSync() + CommonLog.info('getTrustedDeviceListSync = ' + JSON.stringify(list)); + if (typeof (list) != 'undefined' && list.length != 0) { + for (let remoteDevice of list) { + // deviceName刷机后不改变,删除名字相同项目 + for (let i = this.deviceList.length - 1;i >= 0; i--) { + if (this.deviceList[i].deviceName == remoteDevice.deviceName) { + this.deviceList.splice(i, 1); + } + } + CommonLog.info("refreshRemoteDeviceList update deviceName:" + remoteDevice.deviceName) + remoteDevice.status = RemoteDeviceStatus.ONLINE + // 更新最新的设备信息 + this.deviceList.push(remoteDevice); + } + } + }) + } + + /** + * 强制更新deviceList UI视图 + */ + forcedUpdateList(){ + this.deviceList.push(new RemoteDevice("update","update",1,RemoteDeviceStatus.UNTRUSTED)) + this.deviceList.pop() + } + + /** + * 认证设备 + * @param remoteDevice 远程设备 + */ + async authDevice(remoteDevice: RemoteDevice) { + CommonLog.info("authDevice:deviceName=" + remoteDevice.deviceName + " deviceId=" + remoteDevice.deviceId) + await this.init() + return new Promise((resolve, reject) => { + if (remoteDevice.status != RemoteDeviceStatus.UNTRUSTED) { + CommonLog.info("authDevice:device already certified") + resolve("Already certified") + } + // 认证 + let extraInfo = { + "targetPkgName": this.bundleName, + "appName": APP_NAME, + "appDescription": APP_DESCRIPTION, + "business": '0' + }; + let authParam = { + "authType": 1, + "appIcon": '', + "appThumbnail": '', + "extraInfo": extraInfo + } + CommonLog.info("authDevice:start") + this.dmInstance.authenticateDevice(remoteDevice, authParam, (err, data) => { + if (err) { + CommonLog.info(' authenticateDevice failed, err=' + JSON.stringify(err)) + prompt.showToast({message:'authenticateDevice failed, err=' + JSON.stringify(err)}) + reject("fail") // 认证失败 + } else { + CommonLog.info('authenticateDevice succeed, data=' + JSON.stringify(data)) + resolve("success") // 认证成功 + } + }) + CommonLog.info("authDevice:end") + }) + } + + /** + * 启动发现设备 + */ + startDeviceDiscovery() { + CommonLog.info("startDeviceDiscovery") + this.init().then(() => { + this.dmInstance.on('deviceStateChange', (data) => { + CommonLog.info('deviceStateChange data=' + JSON.stringify(data)); + switch (data.action) { + // ONLINE + case 0: + CommonLog.info('ONLINE a device ! deviceInfo=' + JSON.stringify(data.device)) + for (let i = 0; i < this.deviceList.length; i++) { + if (this.deviceList[i].deviceName == data.device.deviceName) { + // 无法检测到深层数据变化,需要将对象拷贝重新赋值 + let device = Object.assign(this.deviceList[i],{}) as RemoteDevice + device.status = RemoteDeviceStatus.ONLINE + device.deviceId = data.device.deviceId + this.deviceList[i] = device + CommonLog.info('Update a online device: ' + JSON.stringify(device)) + this.forcedUpdateList() + return + } + } + let newDevice = { + deviceId: data.device.deviceId, + deviceName: data.device.deviceName, + deviceType: data.device.deviceType, + status: RemoteDeviceStatus.ONLINE + } + CommonLog.info('Found a new online device: deviceName=' + JSON.stringify(newDevice)) + this.deviceList.push(newDevice); + break; + // OFFLINE + case 2: + CommonLog.info('OFFLINE a device !') + for (let i = 0; i < this.deviceList.length; i++) { + if (this.deviceList[i].deviceName == data.device.deviceName) { + CommonLog.info('Delete a offline device: deviceName=' + this.deviceList[i].deviceName) + this.deviceList.splice(i, 1) // 删除当前设备 + return + } + } + CommonLog.info('Not found this offline device in deviceList: ' + data.device.deviceName) + break; + // READY + case 1: + CommonLog.info('READY') + break; + default: + break; + } + }) + + this.dmInstance.on('deviceFound', (data) => { + CommonLog.info('deviceFound deviceName = ' + data.device.deviceName) + for (let i = 0; i < this.deviceList.length; i++) { + if (this.deviceList[i].deviceName == data.device.deviceName) { + this.deviceList[i].deviceId = data.device.deviceId + CommonLog.info('deviceFound device founded in deviceList, update deviceId'); + return; + } + } + let newDevice = { + deviceId: data.device.deviceId, + deviceName: data.device.deviceName, + deviceType: data.device.deviceType, + status: RemoteDeviceStatus.UNTRUSTED + } + CommonLog.info('Found new device: ' + JSON.stringify(newDevice)) + this.deviceList.push(newDevice); + }); + this.dmInstance.on('discoverFail', (data) => { + CommonLog.error(' discoverFail data=' + JSON.stringify(data)) + }); + this.dmInstance.on('serviceDie', () => { + CommonLog.error(' serviceDie') + }); + + let info = { + subscribeId: this.subscribeId, + mode: 0xAA, + medium: 2, + freq: 2, + isSameAccount: false, + isWakeRemote: true, + capability: 0 + }; + this.dmInstance.startDeviceDiscovery(info); + CommonLog.info("startDeviceDiscovery end") + }) + } + + /** + * 停止发现设备 + */ + stopDeviceDiscovery() { + CommonLog.info('stopDeviceDiscovery ' + this.subscribeId); + this.dmInstance.stopDeviceDiscovery(this.subscribeId); + this.dmInstance.off('deviceStateChange'); + this.dmInstance.off('deviceFound'); + this.dmInstance.off('discoverFail'); + this.dmInstance.off('serviceDie'); + // this.deviceList = []; + } +} + diff --git a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceModel.ets b/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceModel.ets deleted file mode 100644 index ccbbafdb..00000000 --- a/FA/Entertainment/BombGame/entry/src/main/ets/MainAbility/pages/RemoteDeviceModel.ets +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import deviceManager from '@ohos.distributedHardware.deviceManager'; -import prompt from '@system.prompt'; - -let SUBSCRIBE_ID = 100; -const TAG = 'BombGame[RemoteDeviceModel] ' - -export default class RemoteDeviceModel { - deviceList = []; - discoverList = []; - callback; - authCallback = null; - #deviceManager; - - constructor() { - } - - registerDeviceListCallback(callback) { - if (typeof (this.#deviceManager) === 'undefined') { - console.log(TAG + ' deviceManager.createDeviceManager begin'); - deviceManager.createDeviceManager('com.sample.bombgame', (error, value) => { - if (error) { - console.error('createDeviceManager failed.'); - return; - } - this.#deviceManager = value; - this.registerDeviceListCallback_(callback); - console.log(TAG + ' createDeviceManager callback returned, error=' + error + ' value=' + value); - }); - console.log(TAG + ' deviceManager.createDeviceManager end'); - } else { - this.registerDeviceListCallback_(callback); - } - } - - registerDeviceListCallback_(callback) { - console.info(TAG + ' registerDeviceListCallback'); - this.callback = callback; - if (this.#deviceManager == undefined) { - console.error(TAG + ' deviceManager has not initialized'); - this.callback(); - return; - } - - console.info(TAG + ' getTrustedDeviceListSync begin'); - let list = this.#deviceManager.getTrustedDeviceListSync(); - console.info(TAG + ' getTrustedDeviceListSync end, deviceList=' + JSON.stringify(list)); - if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') { - this.deviceList = list; - } - this.callback(); - console.info(TAG + ' callback finished'); - - this.#deviceManager.on('deviceStateChange', (data) => { - console.info(TAG + ' deviceStateChange data=' + JSON.stringify(data)); - switch (data.action) { - // ONLINE - case 0: - this.deviceList[this.deviceList.length] = data.device; - this.discoverList = this.discoverList.filter(item=>item.deviceId != data.device.deviceId) - console.info(TAG + ' ONLINE, updated device list=' + JSON.stringify(this.deviceList)); - - this.callback(); - if (this.authCallback != null) { - this.authCallback(); - this.authCallback = null; - } - break; - // OFFLINE - case 2: - if (this.deviceList.length > 0) { - this.deviceList = this.deviceList.filter(item=>item.deviceId != data.device.deviceId) - } - console.info(TAG + ' deviceStateChange OFFLINE deviceId' + data.device.deviceId); - console.info(TAG + ' change, updated device list=' + JSON.stringify(this.deviceList)); - this.callback(); - break; - // READY - case 1: - if (this.deviceList.length > 0) { - let list = []; - for (let i = 0; i < this.deviceList.length; i++) { - if (this.deviceList[i].deviceId != data.device.deviceId) { - list[i] = data.device; - } - } - this.deviceList = list; - } - console.info(TAG + ' READY, updated device list=' + JSON.stringify(data.device)); - this.callback(); - break; - default: - break; - } - }); - this.#deviceManager.on('deviceFound', (data) => { - console.info(TAG + ' deviceFound data=' + JSON.stringify(data)); - console.info(TAG + ' deviceFound self.deviceList=' + this.deviceList); - console.info(TAG + ' deviceFound this.deviceList.length=' + this.deviceList.length); - for (let i = 0; i < this.discoverList.length; i++) { - if (this.discoverList[i].deviceId === data.device.deviceId) { - console.info(TAG + 'deviceFound device founded in discoverList, ignored'); - return; - } - } - this.discoverList[this.discoverList.length] = data.device; - this.callback(); - }); - this.#deviceManager.on('discoverFail', (data) => { - console.info(TAG + ' discoverFail data=' + JSON.stringify(data)); - }); - this.#deviceManager.on('serviceDie', () => { - console.error(TAG + ' serviceDie'); - }); - - SUBSCRIBE_ID = Math.floor(65536 * Math.random()); - let info = { - subscribeId: SUBSCRIBE_ID, - mode: 0xAA, - medium: 2, - freq: 2, - isSameAccount: false, - isWakeRemote: true, - capability: 0 - }; - console.info(TAG + ' startDeviceDiscovery ' + SUBSCRIBE_ID); - this.#deviceManager.startDeviceDiscovery(info); - } - - authDevice(deviceId, callback) { - console.info(TAG + ' authDevice ' + deviceId); - for (let i = 0; i < this.discoverList.length; i++) { - if (this.discoverList[i].deviceId === deviceId) { - console.info(TAG + 'authDevice device founded in discoverList'); - let extraInfo = { - "targetPkgName": 'com.sample.bombgame', - "appName": 'Bomb Game', - "appDescription": 'Bomb Game application', - "business": '0' - }; - let authParam = { - "authType": 1, - "appIcon": '', - "appThumbnail": '', - "extraInfo": extraInfo - }; - console.info(TAG + ' authenticateDevice ' + JSON.stringify(this.discoverList[i])); - this.#deviceManager.authenticateDevice(this.discoverList[i], authParam, (err, data) => { - if (err) { - prompt.showToast({ - message: 'authenticateDevice failed', duration: 5000 - }) - console.info(TAG + ' authenticateDevice failed, err=' + JSON.stringify(err)); - this.authCallback = null; - callback() - } else { - prompt.showToast({ - message: 'authenticateDevice succeed ' + JSON.stringify(data) - }) - console.info(TAG + ' authenticateDevice succeed, data=' + JSON.stringify(data)); - this.authCallback = callback; - } - }); - } - } - } - - unregisterDeviceListCallback() { - console.info(TAG + ' stopDeviceDiscovery ' + SUBSCRIBE_ID); - this.#deviceManager.stopDeviceDiscovery(SUBSCRIBE_ID); - this.#deviceManager.off('deviceStateChange'); - this.#deviceManager.off('deviceFound'); - this.#deviceManager.off('discoverFail'); - this.#deviceManager.off('serviceDie'); - this.deviceList = []; - } -} \ No newline at end of file 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 560da5c3..409089a8 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,13 +13,12 @@ * limitations under the License. */ -import RemoteDeviceModel from './RemoteDeviceModel' +import {RemoteDeviceManager, RemoteDevice, RemoteDeviceStatus} from './RemoteDeviceManager' +import CommonLog from "./CommonLog" import featureAbility from '@ohos.ability.featureAbility'; import prompt from '@system.prompt'; -const TAG = 'BombGame[GamePage]' - -enum TouchType{ +enum TouchType { click = "单击", doubleClick = "双击", longPress = "长按", @@ -29,16 +28,17 @@ const touchMode: Array = [ TouchType.click, TouchType.doubleClick, TouchType.longPress ] -function checkTrustedDevice(remoteDeviceModel: RemoteDeviceModel):boolean { - if (remoteDeviceModel.deviceList.length == 0) { - console.info(TAG + "checkTrustedDevice deviceList is empty") +function checkTrustedDevice(deviceList: RemoteDevice[]): boolean { + let onlineList = deviceList.filter(item => item.status == RemoteDeviceStatus.ONLINE) + if (onlineList.length == 0) { + CommonLog.info("checkTrustedDevice deviceList is empty") prompt.showToast({ message: "No devices found, please make sure they are all on the same network!", duration: 5000 }) return false } else { - console.info(TAG + "checkTrustedDevice length=" + remoteDeviceModel.deviceList.length) + CommonLog.info("checkTrustedDevice length=" + deviceList.length) return true } } @@ -49,22 +49,30 @@ struct Game { @State private duration: number = 3000 @State touchText: TouchType = TouchType.click @State bombIndex: number = 0 + @Provide deviceList: RemoteDevice[] = [] + private remoteDm: RemoteDeviceManager = new RemoteDeviceManager(this.deviceList) private grid: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8] - private remoteDeviceModel = new RemoteDeviceModel() private timer = undefined private transferNumber = 0 private ruleDialog: CustomDialogController = new CustomDialogController({ builder: RuleDialog({ - invite: () => this.InvitePlayer(), + invite: () => this.createPlayerDialog(), confirm: () => this.startGame(), - remoteDeviceModel: this.remoteDeviceModel + deviceList: this.deviceList }), autoCancel: false }) private gameFailDialog: CustomDialogController = new CustomDialogController({ - builder: GameFailDialog({ confirm: () => this.restart(), remoteDeviceModel: this.remoteDeviceModel }), + builder: GameFailDialog({ confirm: () => this.restart(), deviceList: this.deviceList }), autoCancel: false }) + private playerDialog: CustomDialogController = new CustomDialogController({ + builder: PlayerDialog({ + deviceList: this.deviceList, + invite: (remoteDevice) => this.invitePlayer(remoteDevice) + }), + autoCancel: true + }) build() { Column() { @@ -87,25 +95,25 @@ struct Game { .width('50%') .objectFit(ImageFit.Contain) .visibility(this.bombIndex == item ? Visibility.Visible : Visibility.Hidden) - // 炸弹事件 + // 炸弹事件 .onClick((event) => { this.judgeGame(TouchType.click) - console.info(TAG + "onClick") + CommonLog.info("onClick") }) .gesture( GestureGroup(GestureMode.Exclusive, LongPressGesture({ repeat: false }) .onAction((event: GestureEvent) => { - console.info(TAG + "LongPress") + CommonLog.info("LongPress") this.judgeGame(TouchType.longPress) }), TapGesture({ count: 2 }) .onAction(() => { - console.info(TAG + "double click") + CommonLog.info("double click") this.judgeGame(TouchType.doubleClick) }) ).onCancel(() => { - console.info(TAG + "onCancel") + CommonLog.info("onCancel") })) } }.forceRebuild(false) @@ -124,26 +132,29 @@ struct Game { } aboutToAppear() { + CommonLog.module = "Game" featureAbility.getWant((error, want) => { - console.info(TAG + 'featureAbility.parameters' + JSON.stringify(want)); + CommonLog.info('featureAbility.parameters' + JSON.stringify(want)); let status = want.parameters; - if (status.transferNumber) { + if (status && status.transferNumber) { this.transferNumber = status.transferNumber } - if (status.ongoing) { + if (status && status.ongoing) { this.startGame() } else { this.ruleDialog.open() } }); - this.getDeviceList() + this.remoteDm.refreshRemoteDeviceList() + this.remoteDm.startDeviceDiscovery() this.setRandomBomb() + } aboutToDisappear() { - console.info(TAG + 'aboutToDisappear'); + CommonLog.info('aboutToDisappear'); this.stopCountDown() - this.remoteDeviceModel.unregisterDeviceListCallback(); + this.remoteDm.stopDeviceDiscovery() } judgeGame(operation:TouchType) { @@ -162,49 +173,42 @@ struct Game { this.touchText = touchMode[index] } - getDeviceList() { - this.remoteDeviceModel.registerDeviceListCallback(() => { - console.info(TAG + 'getDeviceList registerDeviceListCallback, callback entered'); - }); - } - setRandomBomb() { this.bombIndex = Math.floor(Math.random() * 9) } getRandomDeviceId(): string{ - let randomIndex = Math.floor(Math.random() * this.remoteDeviceModel.deviceList.length) - let deviceId = this.remoteDeviceModel.deviceList[randomIndex].deviceId - console.info(TAG + "getRandomDeviceId deviceId = " + deviceId) + let onlineDeviceList = this.deviceList.filter(item => item.status == RemoteDeviceStatus.ONLINE) + let randomIndex = Math.floor(Math.random() * onlineDeviceList.length) + let deviceId = onlineDeviceList[randomIndex].deviceId + CommonLog.info("getRandomDeviceId deviceId = " + deviceId) return deviceId } startAbilityRandom() { - this.remoteDeviceModel.registerDeviceListCallback(() => { - let deviceId = this.getRandomDeviceId() - console.info(TAG + 'featureAbility.startAbility deviceId=' + deviceId); - let wantValue = { - bundleName: 'com.sample.bombgame', - abilityName: 'com.sample.bombgame.MainAbility', - deviceId: deviceId, - parameters: { - ongoing: true, - transferNumber: this.transferNumber + 1 - } - }; - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info(TAG + ' featureAbility.startAbility finished, ' + JSON.stringify(data)); - featureAbility.terminateSelf((error) => { - console.info(TAG + 'terminateSelf finished, error=' + error); - }); + let deviceId = this.getRandomDeviceId() + CommonLog.info('featureAbility.startAbility deviceId=' + deviceId); + let wantValue = { + bundleName: 'com.sample.bombgame', + 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); }); }); } startGame() { - console.info(TAG + 'startGame'); + CommonLog.info('startGame'); this.randomTouchRule() this.setRandomBomb() this.stopCountDown() @@ -235,7 +239,7 @@ struct Game { prompt.showToast({ message: 'Game Fail' }) - console.info(TAG + 'gameFail'); + CommonLog.info('gameFail'); this.gameFailDialog.open() } @@ -246,29 +250,20 @@ struct Game { } } - InvitePlayer() { - console.info(TAG + " Invite other Player discoverList length:" + this.remoteDeviceModel.discoverList.length) - if (this.remoteDeviceModel.discoverList.length == 0) { - prompt.showToast({ message: "No Other Player!" }) + createPlayerDialog() { + this.playerDialog.open() + } + + invitePlayer(remoteDevice:RemoteDevice) { + if (remoteDevice.status == RemoteDeviceStatus.ONLINE) { + prompt.showToast({ message: "Already invited!" }) return } - let discoverList = this.remoteDeviceModel.discoverList.concat([]) - let fun = () => { - if (discoverList.length != 0) { - let item = discoverList.shift() - if (!item.deviceId) { - return - } - prompt.showToast({ message: "Inviting players:" + item.deviceId }) - console.info(TAG + "start authDevice data " + JSON.stringify(item)) - this.remoteDeviceModel.authDevice(item.deviceId, () => { - fun() - }) - } else { - prompt.showToast({ message: "Invite finish!" }) - } - } - fun() + this.remoteDm.authDevice(remoteDevice).then(() => { + prompt.showToast({ message: "Invite success! deviceName=" + remoteDevice.deviceName }) + }).catch(() => { + prompt.showToast({ message: "Invite fail!" }) + }) } } @@ -277,7 +272,7 @@ struct RuleDialog { controller: CustomDialogController confirm: () => void invite: () => void - remoteDeviceModel: RemoteDeviceModel + @Consume deviceList: RemoteDevice[] build() { Column() { @@ -286,8 +281,8 @@ struct RuleDialog { .fontSize(24).margin({ bottom: 10 }) Image($r("app.media.btn_start")).objectFit(ImageFit.Contain).height(80).margin(10) .onClick(() => { - console.info(TAG + 'Click start game') - if (checkTrustedDevice(this.remoteDeviceModel)) { + CommonLog.info('Click start game') + if (checkTrustedDevice(this.deviceList)) { this.controller.close() this.confirm() } @@ -306,7 +301,7 @@ struct RuleDialog { struct GameFailDialog { @State toggle: boolean = true private controller: CustomDialogController - private remoteDeviceModel: RemoteDeviceModel + @Consume deviceList: RemoteDevice[] private confirm: () => void private isPlayAnimate: boolean = true private interval = null @@ -317,14 +312,13 @@ struct GameFailDialog { 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(() => { - if (checkTrustedDevice(this.remoteDeviceModel)) { + if (checkTrustedDevice(this.deviceList)) { this.controller.close() this.confirm() } @@ -344,11 +338,10 @@ struct GameFailDialog { return } this.stopAnimate() - let fun = () => { - this.toggle = !this.toggle; - } this.interval = setInterval(() => { - animateTo({ duration: 1500, curve: Curve.Sharp }, fun) + animateTo({ duration: 1500, curve: Curve.Sharp }, () => { + this.toggle = !this.toggle; + }) }, 1600) } @@ -362,3 +355,46 @@ struct GameFailDialog { this.stopAnimate() } } + +@CustomDialog +struct PlayerDialog { + private controller: CustomDialogController + @Consume deviceList: RemoteDevice[] + private invite: (remoteDevice: RemoteDevice) => void + + build() { + Column() { + Text("邀请玩家").fontSize(30).fontColor(Color.Black).margin({ top: 20 }) + Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) { + if (this.deviceList.length == 0) { + Text('无在线设备').textAlign(TextAlign.Center).width('100%') + }else{ + ForEach(this.deviceList, item => { + Column() { + if (item.status == RemoteDeviceStatus.ONLINE) { + Image($r("app.media.icon_user")).width('60%').height(100).objectFit(ImageFit.Contain).onClick(()=>{ + prompt.showToast({message:'The player is online'}) + }) + } else { + Image($r("app.media.icon_user_unselect")) + .width('60%') + .height(100) + .objectFit(ImageFit.Contain) + .onClick(() => { + this.invite(item) + }) + } + Text(item.deviceName) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .width('100%') + .maxLines(1) + }.width('33%').height('25%') + }, item => item.deviceId) + } + } + .width('100%') + .margin(50) + .backgroundColor(Color.White) + } + } +} diff --git a/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user.png b/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e6021170850781ad960c3209c0487be8180e05 GIT binary patch literal 4028 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 ia+}v~^q<4O;{6|&n#uxUVUMo>0000s0{vR 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 I$07WG097-qVE_OC literal 0 HcmV?d00001 diff --git a/FA/Entertainment/BombGame/quick_develop.md b/FA/Entertainment/BombGame/quick_develop.md index 822d9e3d..8ce33630 100644 --- a/FA/Entertainment/BombGame/quick_develop.md +++ b/FA/Entertainment/BombGame/quick_develop.md @@ -214,6 +214,12 @@ private ruleDialog: CustomDialogController = new CustomDialogController({ 7)流转接收方可通过[featureAbility](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/js-reference/apis/js-apis-featureAbility.md).getWant()获取到发送方携带的数据; + + +**项目中将上面设备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList设备信息列表,实现分布式流转只需要在deviceList中获取deviceId,然后调用featureAbility.startAbility并携带数据,即可实现分布式流转。** + +![RemoteDeviceManager](resources/RemoteDeviceManager.png) + ### 约束与限制 #### 1. 设备编译约束 diff --git a/FA/Entertainment/BombGame/readme.md b/FA/Entertainment/BombGame/readme.md index 80215505..2ef09e68 100644 --- a/FA/Entertainment/BombGame/readme.md +++ b/FA/Entertainment/BombGame/readme.md @@ -34,7 +34,7 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 打开**OpenHarmony SDK路径 \toolchains** 文件夹下,执行如下hdc_std命令,其中**path**为hap包所在路径。 ```text - hdc_std file install path\entry-debug-standard-ark-signed.hap + hdc_std install -r path\entry-debug-standard-ark-signed.hap ``` #### 应用效果 @@ -51,5 +51,4 @@ demo基于OpenHarmony系统使用ETS语言进行编写,邀请用户进行设 ### 相关链接 -#### [从零开发传炸弹小游戏](quick_develop.md) - +#### [从零开发传炸弹小游戏](quick_develop.md) \ No newline at end of file diff --git a/FA/Entertainment/BombGame/resources/RemoteDeviceManager.png b/FA/Entertainment/BombGame/resources/RemoteDeviceManager.png new file mode 100644 index 0000000000000000000000000000000000000000..32f880bbef67d977662fd13735e6f151e118bc11 GIT binary patch literal 52772 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