12 Star 63 Fork 144

OpenHarmony-SIG / knowledge_demo_temp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
game.ets 11.19 KB
一键复制 编辑 原始数据 按行查看 历史
林嘉诚 提交于 2021-12-08 17:30 . 完善文档 添加注释
/*
* 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 {RemoteDeviceManager, RemoteDevice, RemoteDeviceStatus,getBundleName} from './RemoteDeviceManager'
import CommonLog from "./CommonLog"
import featureAbility from '@ohos.ability.featureAbility';
import prompt from '@system.prompt';
enum RuleType {
click = "单击",
doubleClick = "双击",
longPress = "长按",
}
const touchMode: Array<RuleType> = [
RuleType.click, RuleType.doubleClick, RuleType.longPress
]
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 {
CommonLog.info("checkTrustedDevice length=" + deviceList.length)
return true
}
}
@Entry
@Component
struct Game {
@State private duration: number = 3000
@State ruleText: RuleType = RuleType.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 timer = undefined
private transferNumber = 0
private ruleDialog: CustomDialogController = new CustomDialogController({
builder: RuleDialog({
invite: () => this.createPlayerDialog(),
confirm: () => this.startGame(),
deviceList: this.deviceList
}),
autoCancel: false
})
private gameFailDialog: CustomDialogController = new CustomDialogController({
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() {
Stack() {
Image($r("app.media.title")).objectFit(ImageFit.Contain).height(120)
Column() {
Text(this.duration.toString() + 'ms').fontColor(Color.White)
Text(this.ruleText).fontColor(Color.White)
}
}
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(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%')
}.width('100%')
.height('100%')
.backgroundColor('#2E0259')
}
aboutToAppear() {
CommonLog.module = "Game"
featureAbility.getWant((error, want) => {
CommonLog.info('featureAbility.parameters' + JSON.stringify(want));
let status = want.parameters;
if (status && status.transferNumber) {
this.transferNumber = status.transferNumber
}
if (status && status.ongoing) {
this.startGame() // 继续游戏
} else {
this.ruleDialog.open() // 弹出规则弹框
}
});
this.remoteDm.refreshRemoteDeviceList() // 刷新设备列表
this.remoteDm.startDeviceDiscovery() // 开始发现设备
this.setRandomBomb()
}
aboutToDisappear() {
CommonLog.info('aboutToDisappear');
this.stopCountDown()
this.remoteDm.stopDeviceDiscovery() // 注销监听
}
/**
* 判断游戏输赢
* @param operation 点击类型
*/
judgeGame(operation:RuleType) {
this.stopCountDown()
if (operation != this.ruleText) {
this.gameFail()
} else {
prompt.showToast({ message: "finish" })
this.bombIndex = -1
this.startAbilityRandom()
}
}
/**
* 随机生成点击规则
*/
randomTouchRule() {
let index = Math.floor(Math.random() * 3)
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)
let deviceId = onlineDeviceList[randomIndex].deviceId
CommonLog.info("getRandomDeviceId deviceId = " + deviceId)
return deviceId
}
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);
});
});
}
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)
}
restart() {
this.transferNumber = 0;
this.startGame()
}
gameFail() {
prompt.showToast({
message: 'Game Fail'
})
CommonLog.info('gameFail');
this.gameFailDialog.open()
}
stopCountDown() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}
createPlayerDialog() {
this.playerDialog.open()
}
/**
* 邀请用户(设备认证)
* @param remoteDevice 远程设备
*/
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!" })
})
}
}
@CustomDialog
struct RuleDialog {
controller: CustomDialogController
confirm: () => void
invite: () => void
@Consume deviceList: RemoteDevice[]
build() {
Column() {
Text('游戏规则').fontSize(30).margin(20)
Text('炸弹会随机出现在9个方块内,需要在规定时间内完成指定操作(点击、双击或长按),即可将炸弹传递给下一个人,小心炸弹可是会越来越快的喔!')
.fontSize(24).margin({ bottom: 10 })
Image($r("app.media.btn_start")).objectFit(ImageFit.Contain).height(80).margin(10)
.onClick(() => {
CommonLog.info('Click start game')
if (checkTrustedDevice(this.deviceList)) {
this.controller.close()
this.confirm()
}
})
Image($r("app.media.btn_Invite")).objectFit(ImageFit.Contain).height(80).margin(10)
.onClick(() => {
this.invite()
})
}.width('90%')
.margin(20)
.backgroundColor(Color.White)
}
}
@CustomDialog
struct GameFailDialog {
@State toggle: boolean = true
private controller: CustomDialogController
@Consume deviceList: RemoteDevice[]
private confirm: () => void
private isPlayAnimate: boolean = true
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(() => {
if (checkTrustedDevice(this.deviceList)) {
this.controller.close()
this.confirm()
}
})
}
.width('80%')
.margin(50)
.backgroundColor(Color.White)
}
aboutToAppear() {
this.setBombAnimate()
}
/**
* 设置游戏动画
*/
setBombAnimate() {
if (!this.isPlayAnimate) {
return
}
this.stopAnimate()
this.interval = setInterval(() => {
animateTo({ duration: 1500, curve: Curve.Sharp }, () => {
this.toggle = !this.toggle;
})
}, 1600)
}
stopAnimate() {
if (this.interval) {
clearInterval(this.interval)
}
}
aboutToDisappear() {
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)
}
}
}
1
https://gitee.com/openharmony-sig/knowledge_demo_temp.git
git@gitee.com:openharmony-sig/knowledge_demo_temp.git
openharmony-sig
knowledge_demo_temp
knowledge_demo_temp
master

搜索帮助

14c37bed 8189591 565d56ea 8189591