灌篮少年 发表于 2024-9-20 17:34:57

鸿蒙HarmonyOS项目实战开辟:传炸弹小游戏

简介

demo基于OpenHarmony体系使用ETS语言进行编写,在约请用户进行装备认证后,用户根据操作提示完成相应操作,然后通过分布式流转实现随机传递炸弹的效果。

https://i-blog.csdnimg.cn/blog_migrate/6db6a28b16cecbf8976f1f5ab6228f05.gif
目录

完整的项目布局目录如下
├─entry\src\main
│   │config.json // 应用配置
│   ├─ets
│   │└─MainAbility
│   │      │app.ets //ets应用程序主入口
│   │      └─pages
│   │            CommonLog.ets // 日志类
│   │            game.ets // 游戏首页
│   │            RemoteDeviceManager.ets // 设备管理类
│   └─resources // 静态资源目录
│         ├─base
│         │├─element
│         │├─graphic
│         │├─layout
│         │├─media // 存放媒体资源
│         │└─profile
│         └─rawfile 开辟步骤

1. 新建OpenHarmony ETS项目

在DevEco Studio中点击File -> New Project ->Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。 
https://i-blog.csdnimg.cn/blog_migrate/686fba4325c0844a0b5a08f7806010b4.png
2. 编写游戏页面


https://i-blog.csdnimg.cn/blog_migrate/7adc073a0c446b868be22947539fb211.png
效果图如上可以分为两部分
2.1 顶部状态提示栏

1)起首在@entry组件入口build()中使用Stack作为容器,达到图片和笔墨堆叠的效果;
2)接着依次写入Image和Column包裹的两个Text组件;
Stack() {
   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)
   }
} 2.2 中间游戏炸弹九宫格区域

1)使用Grid网格容器来编写九宫格区域;
2)在GridItem中Stack容器依次添加方块配景图片和炸弹图片;
3)在visibility属性中用bombIndex变量值来决定炸弹显示的位置;
4)通过onClick点击事件和GestureGroup组合手势参加单击、双击和长按的监听事件;
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)
                         })
                         .gesture(
                         GestureGroup(GestureMode.Exclusive,
                         LongPressGesture({ repeat: false })
                           .onAction((event: GestureEvent) => {
                                 // 长按
                                 this.judgeGame(RuleType.longPress)
                           }),
                         TapGesture({ count: 2 })
                           .onAction(() => {
                                 // 双击
                                 this.judgeGame(RuleType.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%') 3. 添加弹窗

3.1 创建规则游戏弹窗

1)通过 @CustomDialog 装饰器来创建自界说弹窗,使用方式可参考 自界说弹窗;
2)规则弹窗效果如下,弹窗构成由两个Text和两个Image竖向排列构成,以是我们可以在build()下使用Column容器来包裹,组件代码如下;

https://i-blog.csdnimg.cn/blog_migrate/e2c3f74fcb24054e8cc8969fcdfb7522.png

   @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(() => {
                  console.info(TAG + 'Click start game')
                  if (checkTrustedDevice(this.remoteDeviceModel)) {
                     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)
      }
   } 3)在@entry创建CustomDialogController对象并传入弹窗所需参数,后面可通过该对象open()和close()方法进行打开和关闭弹窗;
@Provide deviceList: RemoteDevice[] = []
private ruleDialog: CustomDialogController = new CustomDialogController({
   builder: RuleDialog({
      invite: () => this.InvitePlayer(),
      confirm: () => this.startGame(),
      deviceList: this.deviceList
   }),
   autoCancel: false
}) 3.2 创建游戏失败弹窗,并添加动画效果


https://i-blog.csdnimg.cn/blog_migrate/eee6a49cec9feaf06c410f3043d7de68.gif
1)编写弹窗布局:将游戏失败文本、炸弹图片和再来一局按钮图片放置于Column容器中;
2)用变量来控制动画起始和结束的位置:用Flex容器包裹炸弹图片,并用@State装饰变量toggle,通过变量来动态修改Flex的direction属性;
@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 显式动画接口炸弹位置切换时添加动画,而且设置定时器定时执行动画;
aboutToAppear() {
   this.setBombAnimate()
}

setBombAnimate() {
   let fun = () => {
      this.toggle = !this.toggle;
   }
   this.interval = setInterval(() => {
      animateTo({ duration: 1500, curve: Curve.Sharp }, fun)
   }, 1600)
} 4. 添加分布式流转

分布式流转需要在同一网络下通过 DeviceManager组件 进行装备间发现和认证,获取到可信装备的deviceId调用 featureAbility.startAbility ,即可把应用程序流转到另一装备。
本来分布式流转应用流程如下:
1)创建DeviceManager实例;
2)调用实例的startDeviceDiscovery(),开始装备发现未信托装备;
3)设置装备状态监听on('deviceStateChange',callback),监听装备上下线状态;
4)设置装备状态监听on('deviceFound',callback),监听装备发现;
5)传入未信托装备参数,调用实例authenticateDevice方法,对装备进行PIN码认证;
6)如果已信托装备,可通过实例的getTrustedDeviceListSync()方法来获取装备信息;
7)将装备信息中的deviceId传入featureAbility.startAbility方法,实现流转;
8)流转接收方可通过featureAbility.getWant()获取到发送方携带的数据;
9)注销装备发现监听off('deviceFound');
10)注销装备状态监听off('deviceStateChange');
项目中将上面装备管理封装至RemoteDeviceManager,通过RemoteDeviceManager的四个方法来动态维护deviceList装备信息列表。

https://i-blog.csdnimg.cn/blog_migrate/31bd533dbf8153bcb1412eb51752e294.png
项目实现分布式流转只需如下流程:
4.1 创建RemoteDeviceManager实例

1)导入RemoteDeviceManager
import {RemoteDeviceManager} from './RemoteDeviceManager' 2)声明@Provide装饰的装备列表变量deviceList,和创建RemoteDeviceManager实例。
@Provide deviceList: RemoteDevice[] = []
private remoteDm: RemoteDeviceManager = new RemoteDeviceManager(this.deviceList) 4.2 革新装备列表

在生命周期aboutToAppear中,调用革新装备列表和开始发现装备。
aboutToAppear界说:函数在创建自界说组件的新实例后,在执行其build函数之前执行。
aboutToAppear() {
    this.remoteDm.refreshRemoteDeviceList() // 刷新设备列表
    this.remoteDm.startDeviceDiscovery() // 开始发现设备
} 4.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!" })
    })
} 4.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);
      });
    });
} 4.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()
} 最后,有很多小同伴不知道学习哪些鸿蒙开辟技术?不知道需要重点掌握哪些鸿蒙应用开辟知识点?而且学习时频繁踩坑,终极浪费大量时间。以是有一份实用的鸿蒙(Harmony NEXT)资料用来跟着学习是非常有必要的。 
为了能够资助大家快速掌握鸿蒙(Harmony NEXT)应用开辟技术知识。在此给大家分享一下我结合鸿蒙最新资料整理出来的鸿蒙南北向开辟学习门路以及整理的最新版鸿蒙学习文档资料。
这份鸿蒙(Harmony NEXT)资料包含了鸿蒙开辟必掌握的焦点知识要点,内容包含了(ArkTS、ArkUI开辟组件、Stage模型、多端部署、分布式应用开辟、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开辟、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点。
盼望这一份鸿蒙学习资料能够给大家带来资助,有需要的小同伴自行领取,限时开源,先到先得~无套路领取!!
如果你是一名有履历的资深Android移动开辟、Java开辟、前端开辟、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料
 获取这份完整版高清学习门路,请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙(Harmony NEXT)最新学习门路

https://i-blog.csdnimg.cn/blog_migrate/8fb90f03f52981850522a8d70bfe821d.png


[*]  HarmonOS基础技能
https://i-blog.csdnimg.cn/blog_migrate/d15791a8d9157b12cf470e6e20e199cd.png


[*]HarmonOS就业必备技能 https://i-blog.csdnimg.cn/blog_migrate/219a3f80b24947602f5ce80869c0f0d1.png
[*] HarmonOS多媒体技术
https://i-blog.csdnimg.cn/blog_migrate/f76470c4171a878d5f6071f6d009b828.png


[*]鸿蒙NaPi组件进阶
https://i-blog.csdnimg.cn/blog_migrate/8755cfeac3a887ec19fb168f7164234c.png


[*]HarmonOS高级技能
https://i-blog.csdnimg.cn/blog_migrate/1e210328c1ebf43f08d3b6c5f5c13b48.png


[*]初识HarmonOS内核 https://i-blog.csdnimg.cn/blog_migrate/24384aae472f78c055f7bf545467db7f.png
[*]实战就业级装备开辟
https://i-blog.csdnimg.cn/blog_migrate/9b0c4eb9a30ca059d28eceb4727b593e.png
 有了门路图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套体系性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开辟入门讲授视频,内容包含:ArkTS、ArkUI、Web开辟、应用模型、资源分类…等知识点。
获取以上完整版高清学习门路,请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开辟入门讲授视频》

https://i-blog.csdnimg.cn/blog_migrate/9b893c2a4956d6ce72b63212f9216eab.png
《鸿蒙生态应用开辟V2.0白皮书》

https://i-blog.csdnimg.cn/blog_migrate/343917b8910aff13b48316fe3db39da6.jpeg
《鸿蒙 (OpenHarmony)开辟基础到实战手册》

OpenHarmony北向、南向开辟环境搭建
https://i-blog.csdnimg.cn/blog_migrate/2e05bbd2cb0f05ec297905ba57f803c2.png
 《鸿蒙开辟基础》



[*]ArkTS语言
[*]安装DevEco Studio
[*]运用你的第一个ArkTS应用
[*]ArkUI声明式UI开辟
[*].……
https://i-blog.csdnimg.cn/blog_migrate/48e16dbee395ba8de1264149330856d4.png
 《鸿蒙开辟进阶》



[*]Stage模型入门
[*]网络管理
[*]数据管理
[*]电话服务
[*]分布式应用开辟
[*]通知与窗口管理
[*]多媒体技术
[*]安全技能
[*]使命管理
[*]WebGL
[*]国际化开辟
[*]应用测试
[*]DFX面向未来设计
[*]鸿蒙体系移植和裁剪定制
[*]……
https://i-blog.csdnimg.cn/blog_migrate/adf72eca696abc1415cd768fceda1af7.png
《鸿蒙进阶实战》



[*]ArkTS实践
[*]UIAbility应用
[*]网络案例
[*]……
https://i-blog.csdnimg.cn/blog_migrate/c077a46bb540fc657713d99f39e9c74c.png
 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个时机。只有积极应对变化,不断学习和提拔本身,他们才能在这个厘革的时代中立于不败之地。 
https://i-blog.csdnimg.cn/blog_migrate/926f3f942f098baebec15ecf79df9ca9.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 鸿蒙HarmonyOS项目实战开辟:传炸弹小游戏