在 9 月 30號更新的 OpenHarmony3.0 LTS 上,標準系統新增支持了方舟開發框架(ArkUI)、分布式組網和 FA 跨設備遷移能力等新特性,因此我們結合了這三種特性使用 ets 開發了一款如下圖所示傳炸彈應用。
打開應用在通過邀請用戶進行設備認證后,用戶須根據提示完成相應操作,然后通過分布式流轉實現隨機傳遞炸彈給下一位用戶的效果。
那么這樣一款傳炸彈應用如何進行開發呢?完整的項目結構目錄如下:
├─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
我們可以分為如下 3 步:
編寫聲明式 UI 界面
添加分布式能力
編寫游戲邏輯
編寫聲明式UI 界面
①新增工程
在 DevEco Studio 中點擊 File→New Project→Standard Empty Ability→Next,Language 選擇 ETS 語言,最后點擊 Finish 即創建成功。
②編寫游戲頁面
效果圖如下可以分為兩部分:
頂部狀態提示欄:
首先在 @entry 組件入口 build() 中使用 Stack 作為容器,達到圖片和文字堆疊的效果。
接著依次寫入 Image 包裹的兩個 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) } }
中間游戲炸彈九宮格區域:
使用 Grid 網格容器來編寫九宮格區域。
在 GridItem 中 Stack (容器依次添加方塊背景圖片和炸彈圖片。
在 visibility 屬性中用 bombIndex 變量值來決定炸彈顯示的位置。
通過 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('1fr1fr1fr') .rowsTemplate('1fr1fr1fr') .columnsGap(10) .rowsGap(10) .width('90%') .height('75%') }.width('80%').height('70%')③添加彈窗
創建規則游戲彈窗:通過@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
規則彈窗效果如下,彈窗組成由兩個 Text 和兩個 Image 豎向排列組成,所以我們可以在 build() 下使用 Column 容器來包裹。
組件代碼如下:
@CustomDialog structRuleDialog{ controller:CustomDialogController confirm:()=>void invite:()=>void @ConsumedeviceList: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+'Clickstartgame') 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) } }
在 @entry 創建 CustomDialogController 對象并傳入彈窗所需參數,后面可通過該對象 open() 和 close() 方法進行打開和關閉彈窗。
@ProvidedeviceList:RemoteDevice[]=[] privateruleDialog:CustomDialogController=newCustomDialogController({ builder:RuleDialog({ invite:()=>this.InvitePlayer(), confirm:()=>this.startGame(), deviceList:this.deviceList }), autoCancel:false })
創建游戲失敗彈窗,并添加動畫效果,如下圖:
編寫彈窗布局:將游戲失敗文本、炸彈圖片和再來一局按鈕圖片放置于 Column 容器中。
用變量來控制動畫起始和結束的位置:用 Flex 容器包裹炸彈圖片,并用 @State 裝飾變量 toggle,通過變量來動態修改 [Flex] 的 direction 屬性。
@Statetoggle:boolean=true privatecontroller:CustomDialogController @ConsumedeviceList:RemoteDevice[] privateconfirm:()=>void privateinterval=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) }
設置動畫效果:使用 animateTo 顯式動畫接口炸彈位置切換時添加動畫,并且設置定時器定時執行動畫。
aboutToAppear(){ this.setBombAnimate() } setBombAnimate(){ letfun=()=>{ this.toggle=!this.toggle; } this.interval=setInterval(()=>{ animateTo({duration:1500,curve:Curve.Sharp},fun) },1600) }
添加分布式流轉
分布式流轉需要在同一網絡下通過 DeviceManager 組件進行設備間發現和認證。
獲取到可信設備的 deviceId 調用 FeatureAbility.startAbility(parameter),即可把應用程序流轉到另一設備。
原本分布式流轉應用流程如下:
創建 DeviceManager 實例。
調用實例的 startDeviceDiscovery(),開始設備發現未信任設備。
設置設備狀態監聽 on('deviceStateChange',callback),監聽設備上下線狀態。
設置設備狀態監聽 on('deviceFound',callback),監聽設備發現。
傳入未信任設備參數,調用實例 authenticateDevice 方法,對設備進行 PIN 碼認證。
若是已信任設備,可通過實例的 getTrustedDeviceListSync() 方法來獲取設備信息。
將設備信息中的 deviceId 傳入featureAbility.startAbility 方法,實現流轉。
流轉接收方可通過 featureAbility.getWant() 獲取到發送方攜帶的數據。
注銷設備發現監聽 off('deviceFound')。
注銷設備狀態監聽 off('deviceStateChange')。
項目中將上面設備管理封裝至 RemoteDeviceManager,通過 RemoteDeviceManager 的四個方法來動態維護 deviceList 設備信息列表。
項目實現分布式流轉只需如下流程:
①創建 RemoteDeviceManager 實例
導入 RemoteDeviceManager:
import{RemoteDeviceManager}from'./RemoteDeviceManager'
聲明 @Provide 裝飾的設備列表變量 deviceList,和創建 RemoteDeviceManager 實例。
@ProvidedeviceList:RemoteDevice[]=[] privateremoteDm:RemoteDeviceManager=newRemoteDeviceManager(this.deviceList)
②刷新設備列表
在生命周期 aboutToAppear 中,調用刷新設備列表和開始發現設備。
aboutToAppear 定義:函數在創建自定義組件的新實例后,在執行其 build 函數之前執行。
aboutToAppear(){ this.remoteDm.refreshRemoteDeviceList()//刷新設備列表 this.remoteDm.startDeviceDiscovery()//開始發現設備 }
③設備認證
代碼如下:
invitePlayer(remoteDevice:RemoteDevice){ if(remoteDevice.status==RemoteDeviceStatus.ONLINE){ prompt.showToast({message:"Alreadyinvited!"}) return } this.remoteDm.authDevice(remoteDevice).then(()=>{ prompt.showToast({message:"Invitesuccess!deviceName="+remoteDevice.deviceName}) }).catch(()=>{ prompt.showToast({message:"Invitefail!"}) }) }
④跨設備流轉
從 deviceList 中獲取設備列表在線的設備 Id,通過 featureAbility.startAbility 進行流轉。
asyncstartAbilityRandom(){ letdeviceId=this.getRandomDeviceId()//隨機獲取設備id CommonLog.info('featureAbility.startAbilitydeviceId='+deviceId); letbundleName=awaitgetBundleName() letwantValue={ 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.startAbilityfinished,'+JSON.stringify(data)); featureAbility.terminateSelf((error)=>{ CommonLog.info('terminateSelffinished,error='+error); }); }); }⑤注銷監聽
在聲明周期 aboutToDisappear 進行注銷監聽。
aboutToDisappear 定義:函數在自定義組件析構消耗之前執行。
aboutToDisappear(){ this.remoteDm.stopDeviceDiscovery()//注銷監聽 }
編寫游戲邏輯
①開始游戲
代碼如下:
startGame(){ CommonLog.info('startGame'); this.randomTouchRule()//隨機游戲點擊規則 this.setRandomBomb()//隨機生成炸彈位置 this.stopCountDown()//停止倒計時 if(this.transferNumber10)?{ ????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) }
②判斷輸贏
編寫判斷邏輯,用于不同的點擊事件中調用。
/** *判斷游戲輸贏 *@paramoperation點擊類型 */ judgeGame(operation:RuleType){ this.stopCountDown() if(operation!=this.ruleText){ this.gameFail() }else{ prompt.showToast({message:"finish"}) this.bombIndex=-1 this.startAbilityRandom() } }
③游戲失敗
游戲失敗,彈出游戲失敗彈框。
gameFail(){ prompt.showToast({ message:'GameFail' }) CommonLog.info('gameFail'); this.gameFailDialog.open() }
項目下載和導入
項目倉庫地址:
https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/FA/Entertainment/BombGame
①git 下載:
gitclonehttps://gitee.com/openharmony-sig/knowledge_demo_temp.git
②項目導入:打開 DevEco Studio,點擊 File→Open→下載路徑/FA/Entertainment/BombGame。
約束與限制
①設備編譯約束
獲取 OpenHarmony 源碼(OpenHarmony 版本須 3.0LTS 以上):
https://www.openharmony.cn/pages/0001000202/#%E5%AE%89%E8%A3%85%E5%BF%85%E8%A6%81%E7%9A%84%E5%BA%93%E5%92%8C%E5%B7%A5%E5%85%B7
安裝開發板環境:
https://www.openharmony.cn/pages/0001000400/#hi3516%E5%B7%A5%E5%85%B7%E8%A6%81%E6%B1%82
開發板燒錄:
https://www.openharmony.cn/pages/0001000401/#%E4%BD%BF%E7%94%A8%E7%BD%91%E5%8F%A3%E7%83%A7%E5%BD%95
②應用編譯約束
參考《應用開發快速入門》:
https://www.openharmony.cn/pages/00090000/
集成開發環境:DevEco Studio 3.0.0.601 版本以上,下載地址:
https://developer.harmonyos.com/cn/develop/deveco-studio#download_beta
OpenHarmony SDK 3.0.0.0 以上。
作者:林嘉成 OpenAtom OpenHarmony
原文標題:OpenHarmony上玩“傳炸彈”小游戲
文章出處:【微信公眾號:HarmonyOS技術社區】歡迎添加關注!文章轉載請注明出處。
-
容器
+關注
關注
0文章
481瀏覽量
21897 -
OpenHarmony
+關注
關注
24文章
3394瀏覽量
15205
原文標題:OpenHarmony上玩“傳炸彈”小游戲
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論