舒爾特方格游戲,是注意力訓(xùn)練方法之一,可以幫助孩子糾正上課分心走神、回家做作業(yè)拖拉毛病,但不能貪玩哦,玩多了,對(duì)眼睛,視力不好。
①消息通知欄,通知用戶當(dāng)前最優(yōu)成績(jī),也就是當(dāng)前最快時(shí)間。
②元服務(wù)卡片,在桌面上添加 2x2 或 2x4 或 2x4 規(guī)格元服務(wù)卡片,能看到不同布局隨機(jī)數(shù)字,根據(jù)左上角紅色字提示,快速完成點(diǎn)擊,用時(shí)最少為最優(yōu)成績(jī)。
③1x2 規(guī)格元服務(wù)卡片,只顯示當(dāng)前最優(yōu)成績(jī),點(diǎn)擊可以查看 2x2 或 2x4 或 2x4 規(guī)格元服務(wù)卡片最快用時(shí)游戲記錄。
關(guān)系型數(shù)據(jù)庫(kù),用于查詢,添加,更新,刪除元服務(wù)卡片信息和各卡片游戲用時(shí)成績(jī)數(shù)據(jù)。
效果圖如下: 
知識(shí)點(diǎn)
消息通知:提供通知管理的能力,包括發(fā)布、取消發(fā)布通知,創(chuàng)建、獲取、移除通知通道,訂閱、取消訂閱通知,獲取通知的使能狀態(tài)、角標(biāo)使能狀態(tài),獲取通知的相關(guān)信息等。 關(guān)系型數(shù)據(jù)庫(kù):關(guān)系型數(shù)據(jù)庫(kù)基于 SQLite 組件提供了一套完整的對(duì)本地?cái)?shù)據(jù)庫(kù)進(jìn)行管理的機(jī)制,對(duì)外提供了一系列的增、刪、改、查等接口,也可以直接運(yùn)行用戶輸入的 SQL 語(yǔ)句來(lái)滿足復(fù)雜的場(chǎng)景需要。 元服務(wù)卡片開(kāi)發(fā):卡片是一種界面展示形式,可以將應(yīng)用的重要信息或操作前置到卡片,以達(dá)到服務(wù)直達(dá)、減少體驗(yàn)層級(jí)的目的。 卡片提供方:顯示卡片內(nèi)容,控制卡片布局以及控件點(diǎn)擊事件。 卡片使用方:顯示卡片內(nèi)容的宿主應(yīng)用,控制卡片在宿主中展示的位置。 卡片管理服務(wù):用于管理系統(tǒng)中所添加卡片的常駐代理服務(wù),包括卡片對(duì)象的管理與使用,以及卡片周期性刷新等。
軟件要求:
DevEco Studio 版本:DevEco Studio 3.1 Release 及以上版本。
HarmonyOS SDK 版本:API version 9 及以上版本。
硬件要求:
設(shè)備類型:華為手機(jī) 3.1 系統(tǒng)或運(yùn)行在 DevEco Studio 上的遠(yuǎn)程模擬器API9。
HarmonyOS 系統(tǒng):3.1.0 Developer Release 及以上版本。
卡片講解
1x2 卡片主要顯示所有卡片最優(yōu)成績(jī),也就是用時(shí)最少的,同時(shí)點(diǎn)擊卡片,跳轉(zhuǎn)到主界面,查看卡片游戲記錄。

2x2 卡片顯示的是 3x3 布局隨機(jī)生成 1~9 數(shù)字,正上方標(biāo)題顯示挑戰(zhàn)成功或失敗提示,左上角紅色字提示下一個(gè)要點(diǎn)擊的數(shù)字按鈕,右上角顯示當(dāng)次完成后用時(shí)和此卡片用時(shí)最少成績(jī)。
當(dāng)此次的用時(shí)少于最好用時(shí),挑戰(zhàn)成功,并更新數(shù)據(jù)庫(kù)此卡片記錄,如果此次用時(shí)大于最好用時(shí),提示挑戰(zhàn)失敗,不用更新數(shù)據(jù)庫(kù)。

2x4 卡片顯示的是 7x2 布局隨機(jī)生成 1~14 數(shù)字,顯示內(nèi)容和游戲規(guī)則與 2x2 卡片一樣。

4x4 卡片顯示的是 6x6 布局隨機(jī)生成 1~36 數(shù)字,顯示內(nèi)容和游戲規(guī)則與 2x2 卡片一樣。

首次啟動(dòng)或點(diǎn)擊 1x2 卡片進(jìn)入到主界面,主界面顯示各卡片游戲成績(jī)記錄。

通知顯示效果:

代碼講解
數(shù)據(jù)庫(kù)操作后端項(xiàng)目結(jié)構(gòu)圖:

FormData.ets 實(shí)體類代碼如下:
exportdefaultclassFormData{
//卡片ID
formId:string;
//距陣數(shù)3x3
matrixNum:string;
//最優(yōu)成績(jī)
bestScore:number;
//總最優(yōu)成績(jī)
totalBestScore:number;
}
Form.ets 數(shù)據(jù)庫(kù)卡片表如下:
exportdefaultclassForm{
//卡片ID
formId:string;
//卡片名稱
formName:string;
//卡片描述
dimension:number;
/**
*封裝卡片數(shù)據(jù)
*@returns
*/
toValuesBucket(){
return{
'formId':this.formId,
'formName':this.formName,
'dimension':this.dimension
};
}
}
ScoreData.ets 游戲記錄成績(jī)表如下:
exportdefaultclassScoreData{
//卡片
formId:string;
//距陣數(shù)3x3
matrixNum:string;
//最優(yōu)成績(jī)
bestScore:number;
/**
*獲取插入成績(jī)記錄數(shù)
*@returns
*/
toValuesBucket(){
return{
'formId':this.formId,
'matrixNum':this.matrixNum,
'bestScore':this.bestScore
};
}
}
DatabaseUtils.ets 數(shù)據(jù)庫(kù)操作類部分代碼如下:
exportclassDatabaseUtils{
/**
*創(chuàng)建RDB數(shù)據(jù)庫(kù)
*
*@param{context}上下文
*@return{globalThis.rdbStore}returnrdbStoreRDB數(shù)據(jù)庫(kù)
*/
asynccreateRdbStore(context:Context){
console.info(CommonConstants.DATABASE_TAG,'xxDatabaseUtils-createRdbStore開(kāi)始...')
//如果全局變量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)建成績(jī)表
rdbStore.executeSql(CommonConstants.CREATE_TABLE_SCORE_DATA).catch((error)=>{
console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 創(chuàng)建成績(jī)表失?。?+JSON.stringify(error))
Logger.error(CommonConstants.DATABASE_TAG,'executeSqlSensorerror'+JSON.stringify(error));
});
//存儲(chǔ)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ù)庫(kù)失?。?+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結(jié)束...')
returnglobalThis.rdbStore;
}
/**
*插入卡片數(shù)據(jù)。
*
*@param{Form}Form表單實(shí)體。
*@param{DataRdb.RdbStore}RDB存儲(chǔ)RDB數(shù)據(jù)庫(kù)。
*@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));
});
}
/**
*將成績(jī)插入數(shù)據(jù)庫(kù)。
*
*@param{ScoreData}scoreData。
*@param{DataRdb.RdbStore}RDB存儲(chǔ)RDB數(shù)據(jù)庫(kù)。
*/
insertValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){
rdbStore.insert(CommonConstants.TABLE_SCORE,scoreData.toValuesBucket()).catch((error)=>{
Logger.error(CommonConstants.DATABASE_TAG,'insertValueserror'+JSON.stringify(error));
});
}
/**
*更新成績(jī)到數(shù)據(jù)庫(kù)
*@paramscoreData
*@paramrdbStore
*/
updateValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){}
/**
*刪除卡片數(shù)據(jù)。
*
*@param{string}formId表單ID。
*@param{DataRdb.RdbStore}RDB存儲(chǔ)RDB數(shù)據(jù)庫(kù)。
*/
deleteFormData(formId:string,rdbStore:DataRdb.RdbStore){}
/**
*更新卡片
*
*@param{DataRdb.RdbStore}RDB存儲(chǔ)RDB數(shù)據(jù)庫(kù)。
*/
updateForms(rdbStore:DataRdb.RdbStore){}
/**
*發(fā)送通知
*
*@param{string}Steps顯示的值步數(shù)。
*/
asyncsendNotifications(score:number){}
}
卡片前端項(xiàng)目結(jié)構(gòu)圖:

EntryAbility.ets 程序入口初始化數(shù)據(jù)庫(kù)代碼如下:
onCreate(want,launchParam){
//數(shù)據(jù)庫(kù)初始化
globalThis.abilityWant=want;
globalThis.abilityParam=launchParam;
console.info(CommonConstants.ENTRY_ABILITY_TAG,'xxonCreate創(chuàng)建RDB數(shù)據(jù)庫(kù)')
//創(chuàng)建RDB數(shù)據(jù)庫(kù)
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ù)庫(kù)失?。?+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ù)庫(kù)
DatabaseUtils.insertForm(form,rdbStore);
//獲取最優(yōu)成績(jī)
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);
}
卡片頁(yè)面部分代碼,這里就顯示 2x2 卡片代碼如下:
build(){
Column(){
Text(this.message)
.width('100%')
.fontSize(12)
.textAlign(TextAlign.Center)
.fontWeight(700)
.margin({top:6,bottom:6})
Row(){
Text(`下一個(gè):${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%')
}
總結(jié)
通過(guò)開(kāi)發(fā)這個(gè)小游戲元服務(wù),學(xué)習(xí)到不少知識(shí),其實(shí)我有嘗試過(guò)把數(shù)據(jù)庫(kù)操作類寫到動(dòng)態(tài)共享包里,這樣元服務(wù)打包后不就更小了,然而啟動(dòng)后白屏了,進(jìn)步問(wèn)題,等華為相關(guān)技術(shù)人員回復(fù),想學(xué)習(xí)動(dòng)態(tài)共享包的,可以參考關(guān)系型數(shù)據(jù)庫(kù)-動(dòng)態(tài)共享包開(kāi)發(fā)。 總結(jié)這個(gè)項(xiàng)目用到以下知識(shí)點(diǎn):
使用 notification 發(fā)布通知。
使用關(guān)系型數(shù)據(jù)庫(kù)插入、更新、刪除卡片數(shù)據(jù)。
使用 FormExtensionAbility 創(chuàng)建、更新、刪除元服務(wù)卡片。
-
華為
+關(guān)注
關(guān)注
218文章
36007瀏覽量
262124 -
游戲
+關(guān)注
關(guān)注
2文章
790瀏覽量
27469 -
數(shù)據(jù)庫(kù)
+關(guān)注
關(guān)注
7文章
4020瀏覽量
68359 -
HarmonyOS
+關(guān)注
關(guān)注
80文章
2153瀏覽量
36062 -
OpenHarmony
+關(guān)注
關(guān)注
33文章
3952瀏覽量
21112
原文標(biāo)題:HarmonyOS 3.1上實(shí)現(xiàn)“游戲萬(wàn)能卡片”
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
HarmonyOS服務(wù)卡片跑AIGC
HarmonyOSAI編程萬(wàn)能卡片生成(一)
HarmonyOSAI編程萬(wàn)能卡片生成(二)
HarmonyOS萬(wàn)能服務(wù)卡片開(kāi)發(fā)嘗試歷程(一)
李洋:手把手教你開(kāi)發(fā)一個(gè)元服務(wù)萬(wàn)能卡片
用HarmonyOS元服務(wù)萬(wàn)能卡片訓(xùn)練一下文心一言的AIGC能力
HarmonyOS元服務(wù)開(kāi)發(fā)實(shí)踐:桌面卡片字典
HarmonyOS/OpenHarmony原生應(yīng)用-ArkTS萬(wàn)能卡片組件Stack
HarmonyOS開(kāi)發(fā)案例分享:萬(wàn)能卡片也能用來(lái)玩游戲
帶你探究萬(wàn)能卡片的一些用處
HarmonyOS 3.1上實(shí)現(xiàn)計(jì)步卡片
【開(kāi)發(fā)者說(shuō)】開(kāi)發(fā)案例分享:萬(wàn)能卡片也能用來(lái)玩游戲
開(kāi)發(fā)案例分享:萬(wàn)能卡片也能用來(lái)玩游戲
效率大升!AI賦能鴻蒙萬(wàn)能卡片開(kāi)發(fā)
HarmonyOS 3.1上實(shí)現(xiàn)游戲萬(wàn)能卡片
評(píng)論