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 0000000000000000000000000000000000000000..24297ac7d6aad1c01d789cf1097343afa27b9743 --- /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 0000000000000000000000000000000000000000..aaf8ddcd772a274cf47cbe626a83361fedb039ad --- /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 ccbbafdba34a2540fae0f3b4baa3bbe325ac08ed..0000000000000000000000000000000000000000 --- 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 560da5c30705a395383dd61978e1e9e98b2f2a97..409089a8e3a25012e7887ee80cfe7f4747505410 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 Binary files /dev/null and b/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user.png differ diff --git a/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user_unselect.png b/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user_unselect.png new file mode 100644 index 0000000000000000000000000000000000000000..d0b64d9772dc436cf3c52b2226abbc0cf6517dd9 Binary files /dev/null and b/FA/Entertainment/BombGame/entry/src/main/resources/base/media/icon_user_unselect.png differ diff --git a/FA/Entertainment/BombGame/quick_develop.md b/FA/Entertainment/BombGame/quick_develop.md index 822d9e3dfa3f814868199c1a7240f0ba8532e83b..8ce3363063e3b54bd5984e614f6757eff316b7f4 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 802155057930880e92107d256100e1f07c07f2d8..2ef09e680b3bf28e5eedf7aa43ce689cf6975d8f 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 Binary files /dev/null and b/FA/Entertainment/BombGame/resources/RemoteDeviceManager.png differ diff --git a/FA/Entertainment/TicTacToeGame/README.md b/FA/Entertainment/TicTacToeGame/README.md index 31944d9123bb7ac49aaccf13255dacb0f82ad074..c7f9a253b0ad081e01821927b76f3b2aab16aab3 100644 --- a/FA/Entertainment/TicTacToeGame/README.md +++ b/FA/Entertainment/TicTacToeGame/README.md @@ -41,7 +41,7 @@ Demo基于Open Harmony系统使用ETS语言进行编写,本Demo主要通过设 打开**OpenHarmony SDK路径 \toolchains** 文件夹下,执行如下hdc_std命令,其中**path**为hap包所在路径。 ``` - hdc_std file install path\entry-debug-standard-ark-signed.hap + hdc_std install -r path\entry-debug-standard-ark-signed.hap ```