舒爾特方格游戲,是注意力訓練方法之一,可以幫助孩子糾正上課分心走神、回家做作業(yè)拖拉毛病,但不能貪玩哦,玩多了,對眼睛,視力不好。
①消息通知欄,通知用戶當前最優(yōu)成績,也就是當前最快時間。
②元服務卡片,在桌面上添加 2x2 或 2x4 或 2x4 規(guī)格元服務卡片,能看到不同布局隨機數(shù)字,根據(jù)左上角紅色字提示,快速完成點擊,用時最少為最優(yōu)成績。
③1x2 規(guī)格元服務卡片,只顯示當前最優(yōu)成績,點擊可以查看 2x2 或 2x4 或 2x4 規(guī)格元服務卡片最快用時游戲記錄。
關系型數(shù)據(jù)庫,用于查詢,添加,更新,刪除元服務卡片信息和各卡片游戲用時成績數(shù)據(jù)。
效果圖如下:
知識點
消息通知:提供通知管理的能力,包括發(fā)布、取消發(fā)布通知,創(chuàng)建、獲取、移除通知通道,訂閱、取消訂閱通知,獲取通知的使能狀態(tài)、角標使能狀態(tài),獲取通知的相關信息等。 關系型數(shù)據(jù)庫:關系型數(shù)據(jù)庫基于 SQLite 組件提供了一套完整的對本地數(shù)據(jù)庫進行管理的機制,對外提供了一系列的增、刪、改、查等接口,也可以直接運行用戶輸入的 SQL 語句來滿足復雜的場景需要。 元服務卡片開發(fā):卡片是一種界面展示形式,可以將應用的重要信息或操作前置到卡片,以達到服務直達、減少體驗層級的目的。 卡片提供方:顯示卡片內(nèi)容,控制卡片布局以及控件點擊事件。 卡片使用方:顯示卡片內(nèi)容的宿主應用,控制卡片在宿主中展示的位置。 卡片管理服務:用于管理系統(tǒng)中所添加卡片的常駐代理服務,包括卡片對象的管理與使用,以及卡片周期性刷新等。
軟件要求:
DevEco Studio 版本:DevEco Studio 3.1 Release 及以上版本。
HarmonyOS SDK 版本:API version 9 及以上版本。
硬件要求:
設備類型:華為手機 3.1 系統(tǒng)或運行在 DevEco Studio 上的遠程模擬器API9。
HarmonyOS 系統(tǒng):3.1.0 Developer Release 及以上版本。
卡片講解
1x2 卡片主要顯示所有卡片最優(yōu)成績,也就是用時最少的,同時點擊卡片,跳轉到主界面,查看卡片游戲記錄。
2x2 卡片顯示的是 3x3 布局隨機生成 1~9 數(shù)字,正上方標題顯示挑戰(zhàn)成功或失敗提示,左上角紅色字提示下一個要點擊的數(shù)字按鈕,右上角顯示當次完成后用時和此卡片用時最少成績。
當此次的用時少于最好用時,挑戰(zhàn)成功,并更新數(shù)據(jù)庫此卡片記錄,如果此次用時大于最好用時,提示挑戰(zhàn)失敗,不用更新數(shù)據(jù)庫。
2x4 卡片顯示的是 7x2 布局隨機生成 1~14 數(shù)字,顯示內(nèi)容和游戲規(guī)則與 2x2 卡片一樣。
4x4 卡片顯示的是 6x6 布局隨機生成 1~36 數(shù)字,顯示內(nèi)容和游戲規(guī)則與 2x2 卡片一樣。
首次啟動或點擊 1x2 卡片進入到主界面,主界面顯示各卡片游戲成績記錄。
通知顯示效果:
代碼講解
數(shù)據(jù)庫操作后端項目結構圖:
FormData.ets 實體類代碼如下:
exportdefaultclassFormData{ //卡片ID formId:string; //距陣數(shù)3x3 matrixNum:string; //最優(yōu)成績 bestScore:number; //總最優(yōu)成績 totalBestScore:number; }
Form.ets 數(shù)據(jù)庫卡片表如下:
exportdefaultclassForm{ //卡片ID formId:string; //卡片名稱 formName:string; //卡片描述 dimension:number; /** *封裝卡片數(shù)據(jù) *@returns */ toValuesBucket(){ return{ 'formId':this.formId, 'formName':this.formName, 'dimension':this.dimension }; } }
ScoreData.ets 游戲記錄成績表如下:
exportdefaultclassScoreData{ //卡片 formId:string; //距陣數(shù)3x3 matrixNum:string; //最優(yōu)成績 bestScore:number; /** *獲取插入成績記錄數(shù) *@returns */ toValuesBucket(){ return{ 'formId':this.formId, 'matrixNum':this.matrixNum, 'bestScore':this.bestScore }; } }
DatabaseUtils.ets 數(shù)據(jù)庫操作類部分代碼如下:
exportclassDatabaseUtils{ /** *創(chuàng)建RDB數(shù)據(jù)庫 * *@param{context}上下文 *@return{globalThis.rdbStore}returnrdbStoreRDB數(shù)據(jù)庫 */ asynccreateRdbStore(context:Context){ console.info(CommonConstants.DATABASE_TAG,'xxDatabaseUtils-createRdbStore開始...') //如果全局變量rdbStore不存在,創(chuàng)建 if(!globalThis.rdbStore){ console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 新創(chuàng)建!') awaitDataRdb.getRdbStore(context,CommonConstants.RDB_STORE_CONFIG) .then((rdbStore)=>{ console.info(CommonConstants.DATABASE_TAG,'xxRDBStore回調(diào)') if(rdbStore){ //創(chuàng)建卡片表 rdbStore.executeSql(CommonConstants.CREATE_TABLE_FORM).catch((error)=>{ console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 創(chuàng)建卡片表失敗:'+JSON.stringify(error)) Logger.error(CommonConstants.DATABASE_TAG,'executeSqlFormerror'+JSON.stringify(error)); }); //創(chuàng)建成績表 rdbStore.executeSql(CommonConstants.CREATE_TABLE_SCORE_DATA).catch((error)=>{ console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 創(chuàng)建成績表失?。?+JSON.stringify(error)) Logger.error(CommonConstants.DATABASE_TAG,'executeSqlSensorerror'+JSON.stringify(error)); }); //存儲RDBStore到全局變量 globalThis.rdbStore=rdbStore; console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 創(chuàng)建成功!') } }).catch((error)=>{ console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 創(chuàng)建RDB數(shù)據(jù)庫失?。?+JSON.stringify(error)) Logger.error(CommonConstants.DATABASE_TAG,'createRdbStoreerror'+JSON.stringify(error)); }); }else{ console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 已經(jīng)存在!') } console.info(CommonConstants.DATABASE_TAG,'xxDatabaseUtils-createRdbStore結束...') returnglobalThis.rdbStore; } /** *插入卡片數(shù)據(jù)。 * *@param{Form}Form表單實體。 *@param{DataRdb.RdbStore}RDB存儲RDB數(shù)據(jù)庫。 *@return返回操作信息。 */ insertForm(form:Form,rdbStore:DataRdb.RdbStore){ rdbStore.insert(CommonConstants.TABLE_FORM,form.toValuesBucket()).catch((error)=>{ Logger.error(CommonConstants.DATABASE_TAG,'insertFormerror'+JSON.stringify(error)); }); } /** *將成績插入數(shù)據(jù)庫。 * *@param{ScoreData}scoreData。 *@param{DataRdb.RdbStore}RDB存儲RDB數(shù)據(jù)庫。 */ insertValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){ rdbStore.insert(CommonConstants.TABLE_SCORE,scoreData.toValuesBucket()).catch((error)=>{ Logger.error(CommonConstants.DATABASE_TAG,'insertValueserror'+JSON.stringify(error)); }); } /** *更新成績到數(shù)據(jù)庫 *@paramscoreData *@paramrdbStore */ updateValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){} /** *刪除卡片數(shù)據(jù)。 * *@param{string}formId表單ID。 *@param{DataRdb.RdbStore}RDB存儲RDB數(shù)據(jù)庫。 */ deleteFormData(formId:string,rdbStore:DataRdb.RdbStore){} /** *更新卡片 * *@param{DataRdb.RdbStore}RDB存儲RDB數(shù)據(jù)庫。 */ updateForms(rdbStore:DataRdb.RdbStore){} /** *發(fā)送通知 * *@param{string}Steps顯示的值步數(shù)。 */ asyncsendNotifications(score:number){} }
卡片前端項目結構圖:
EntryAbility.ets 程序入口初始化數(shù)據(jù)庫代碼如下:
onCreate(want,launchParam){ //數(shù)據(jù)庫初始化 globalThis.abilityWant=want; globalThis.abilityParam=launchParam; console.info(CommonConstants.ENTRY_ABILITY_TAG,'xxonCreate創(chuàng)建RDB數(shù)據(jù)庫') //創(chuàng)建RDB數(shù)據(jù)庫 DatabaseUtils.createRdbStore(this.context).then((rdbStore)=>{ console.info(CommonConstants.ENTRY_ABILITY_TAG,'xxonCreateRDB成功') }).catch((error)=>{ console.error(CommonConstants.ENTRY_ABILITY_TAG,'xx onCreate 創(chuàng)建數(shù)據(jù)庫失?。?+JSON.stringify(error)) Logger.error(CommonConstants.ENTRY_ABILITY_TAG,'onCreaterdberror'+JSON.stringify(error)); }); }
EntryFormAbility.ets 卡片生命周期代碼如下:
onAddForm(want){ //獲取卡片ID:ohos.extra.param.key.form_identity letformId:string=want.parameters[CommonConstants.FORM_PARAM_IDENTITY_KEY]asstring; //獲取卡片名稱:ohos.extra.param.key.form_name letformName:string=want.parameters[CommonConstants.FORM_PARAM_NAME_KEY]asstring; //獲取卡片規(guī)格:ohos.extra.param.key.form_dimension letdimensionFlag:number=want.parameters[CommonConstants.FORM_PARAM_DIMENSION_KEY]asnumber; console.info(CommonConstants.ENTRY_FORM_ABILITY_TAG,`xx 添加卡片是:${formId}${dimensionFlag}${dimensionFlag}`) DatabaseUtils.createRdbStore(this.context).then((rdbStore)=>{ //卡片信息 letform:Form=newForm(); form.formId=formId; form.formName=formName; form.dimension=dimensionFlag; console.info(CommonConstants.ENTRY_FORM_ABILITY_TAG,'xx onAddForm 新增卡片信息:'+JSON.stringify(form)) //保存卡片信息到數(shù)據(jù)庫 DatabaseUtils.insertForm(form,rdbStore); //獲取最優(yōu)成績 getBestScore(rdbStore,dimensionFlag,formId); }).catch((error)=>{ console.error(CommonConstants.ENTRY_FORM_ABILITY_TAG,'xx onAddForm 添加卡片失敗:'+JSON.stringify(error)) Logger.error(CommonConstants.ENTRY_FORM_ABILITY_TAG,'onAddFormrdberror'+JSON.stringify(error)); }); //每五分鐘刷新一次 formProvider.setFormNextRefreshTime(formId,CommonConstants.FORM_NEXT_REFRESH_TIME,(error,data)=>{ if(error){ console.error(CommonConstants.ENTRY_FORM_ABILITY_TAG,'xx onAddForm 更新卡片失?。?+JSON.stringify(error)) Logger.error(CommonConstants.ENTRY_FORM_ABILITY_TAG,'refreshTime,error:'+JSON.stringify(error)); }else{ console.info(CommonConstants.ENTRY_FORM_ABILITY_TAG,'xxonAddForm更新卡片成功') Logger.info(CommonConstants.ENTRY_FORM_ABILITY_TAG,'refreshTimesuccess'+JSON.stringify(data)); } }); //返回初始化卡片數(shù)據(jù) letformData:FormData=newFormData(); formData.formId=formId; formData.bestScore=0; formData.matrixNum='1x1'; formData.totalBestScore=0; returnformBindingData.createFormBindingData(formData); }
卡片頁面部分代碼,這里就顯示 2x2 卡片代碼如下:
build(){ Column(){ Text(this.message) .width('100%') .fontSize(12) .textAlign(TextAlign.Center) .fontWeight(700) .margin({top:6,bottom:6}) Row(){ Text(`下一個:${this.flagNum==0?1:this.flagNum}`) .fontSize(10).fontWeight(400) .fontColor(Color.Red) Row(){ Text(`此次:${this.currentScore}`) .fontSize(10).fontWeight(400) Text(`最好:${this.bestScore}`) .fontSize(10).fontWeight(400) } } .width('100%') .padding({left:10,right:10}) .alignItems(VerticalAlign.Center) .justifyContent(FlexAlign.SpaceBetween) Flex({justifyContent:FlexAlign.Center,alignItems:ItemAlign.Center,wrap:FlexWrap.Wrap}){ //循環(huán)顯示數(shù)字按鈕 ForEach(this.numArray,(day:string)=>{ Button(day,{type:ButtonType.Circle,stateEffect:true}) .width(40) .height(40) .padding(1) .margin(4) .fontSize(12) .backgroundColor(Color.Gray) .stateStyles({ normal:this.normalStyles, pressed:this.pressedStyles }) .onClick(()=>{this.startGame(Number(day))}) },day=>day) } .width('100%') .height('100%') .padding({top:2,left:5,right:5}) } .width('100%') .height('100%') }
總結
通過開發(fā)這個小游戲元服務,學習到不少知識,其實我有嘗試過把數(shù)據(jù)庫操作類寫到動態(tài)共享包里,這樣元服務打包后不就更小了,然而啟動后白屏了,進步問題,等華為相關技術人員回復,想學習動態(tài)共享包的,可以參考關系型數(shù)據(jù)庫-動態(tài)共享包開發(fā)。 總結這個項目用到以下知識點:
使用 notification 發(fā)布通知。
使用關系型數(shù)據(jù)庫插入、更新、刪除卡片數(shù)據(jù)。
使用 FormExtensionAbility 創(chuàng)建、更新、刪除元服務卡片。
-
華為
+關注
關注
215文章
34258瀏覽量
250989 -
游戲
+關注
關注
2文章
733瀏覽量
26261 -
數(shù)據(jù)庫
+關注
關注
7文章
3752瀏覽量
64233 -
HarmonyOS
+關注
關注
79文章
1966瀏覽量
29962 -
OpenHarmony
+關注
關注
25文章
3635瀏覽量
16061
原文標題:HarmonyOS 3.1上實現(xiàn)“游戲萬能卡片”
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區(qū)】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論