新聞中心
想了解更多關(guān)于開源的內(nèi)容,請訪問:

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供婁煩企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、H5技術(shù)、小程序制作等業(yè)務(wù)。10年已為婁煩眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進行中。
開源基礎(chǔ)軟件社區(qū)
https://ost.
前言
舒爾特方格游戲,是注意力訓(xùn)練方法之一,可以幫助孩子糾正上課分心走神、回家做作業(yè)拖拉毛病,但不能貪玩哦,玩多了,對眼睛,視力不好。
1. 消息通知欄,通知用戶當(dāng)前最優(yōu)成績,也就是當(dāng)前最快時間。2. 元服務(wù)卡片,在桌面上添加2x2或2x4或2x4規(guī)格元服務(wù)卡片,能看到不同布局隨機數(shù)字,根據(jù)左上角紅色字提示,快速完成點擊,用時最少為最優(yōu)成績,1x2規(guī)格元服務(wù)卡片,只顯示當(dāng)前最優(yōu)成績,點擊可以3. 關(guān)系型數(shù)據(jù)庫,用于查詢,添加,更新,刪除元服務(wù)卡片信息和各卡片游戲用時成績數(shù)據(jù)。
B站高清演示視頻
知識點
- 消息通知:提供通知管理的能力,包括發(fā)布、取消發(fā)布通知,創(chuàng)建、獲取、移除通知通道,訂閱、取消訂閱通知,獲取通知的使能狀態(tài)、角標(biāo)使能狀態(tài),獲取通知的相關(guān)信息等。
- 關(guān)系型數(shù)據(jù)庫:關(guān)系型數(shù)據(jù)庫基于SQLite組件提供了一套完整的對本地數(shù)據(jù)庫進行管理的機制,對外提供了一系列的增、刪、改、查等接口,也可以直接運行用戶輸入的SQL語句來滿足復(fù)雜的場景需要。
- 元服務(wù)卡片開發(fā):卡片是一種界面展示形式,可以將應(yīng)用的重要信息或操作前置到卡片,以達到服務(wù)直達、減少體驗層級的目的。
- 卡片提供方:顯示卡片內(nèi)容,控制卡片布局以及控件點擊事件。
- 卡片使用方:顯示卡片內(nèi)容的宿主應(yīng)用,控制卡片在宿主中展示的位置。
- 卡片管理服務(wù):用于管理系統(tǒng)中所添加卡片的常駐代理服務(wù),包括卡片對象的管理與使用,以及卡片周期性刷新等。
- 軟件要求
- DevEco Studio版本:DevEco Studio 3.1 Release及以上版本。
- HarmonyOS SDK版本:API version 9及以上版本。
- 硬件要求
- 設(shè)備類型:華為手機3.1系統(tǒng)或運行在DevEco Studio上的遠程模擬器API9。
- HarmonyOS系統(tǒng):3.1.0 Developer Release及以上版本。
卡片講解
1. 1x2卡片主要顯示所有卡片最優(yōu)成績,也就是用時最少的,同時點擊卡片,跳轉(zhuǎn)到主界面,查看卡片游戲記錄。
2. 2x2卡片顯示的是3x3布局隨機生成1~9數(shù)字,正上方標(biāo)題顯示挑戰(zhàn)成功或失敗提示,左上角紅色字提示下一個要點擊的數(shù)字按鈕,右上角顯示當(dāng)次完成后用時和此卡片用時最少成績,當(dāng)此次的用時少于最好用時,挑戰(zhàn)成功,并更新數(shù)據(jù)庫此卡片記錄,如果此次用時大于最好用時,提示挑戰(zhàn)失敗,不用更新數(shù)據(jù)庫。
3. 2x4卡片顯示的是7x2布局隨機生成1~14數(shù)字,顯示內(nèi)容和游戲規(guī)則與2x2卡片一樣。
4. 4x4卡片顯示的是6x6布局隨機生成1~36數(shù)字,顯示內(nèi)容和游戲規(guī)則與2x2卡片一樣。
5. 首次啟動或點擊1x2卡片進入到主界面,主界面顯示各卡片游戲成績記錄。
6. 通知顯示效果。
代碼講解
1. 數(shù)據(jù)庫操作后端項目結(jié)構(gòu)圖。
FormData.ets實體類代碼如下:
export default class FormData {
// 卡片ID
formId: string;
// 距陣數(shù) 3x3
matrixNum: string;
// 最優(yōu)成績
bestScore: number;
// 總最優(yōu)成績
totalBestScore: number;
}Form.ets數(shù)據(jù)庫卡片表如下:
export default class Form {
// 卡片ID
formId: string;
// 卡片名稱
formName: string;
// 卡片描述
dimension: number;
/**
* 封裝卡片數(shù)據(jù)
* @returns
*/
toValuesBucket() {
return {
'formId': this.formId,
'formName': this.formName,
'dimension': this.dimension
};
}
}ScoreData.ets游戲記錄成績表如下:
export default class ScoreData {
// 卡片
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ù)庫操作類部分代碼如下:
export class DatabaseUtils {
/**
* 創(chuàng)建RDB數(shù)據(jù)庫
*
* @param{context}上下文
* @return{globalThis.rdbStore}return rdbStore RDB數(shù)據(jù)庫
*/
async createRdbStore(context: Context) {
console.info(CommonConstants.DATABASE_TAG, 'xx DatabaseUtils-createRdbStore 開始...')
// 如果全局變量rdbStore不存在,創(chuàng)建
if (!globalThis.rdbStore) {
console.info(CommonConstants.DATABASE_TAG, 'xx DatabaseUtils-createRdbStore 新創(chuàng)建!')
await DataRdb.getRdbStore(context, CommonConstants.RDB_STORE_CONFIG)
.then((rdbStore) => {
console.info(CommonConstants.DATABASE_TAG, 'xx RDB Store回調(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, 'executeSql Form error ' + 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, 'executeSql Sensor error ' + 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, 'createRdbStore error ' + JSON.stringify(error));
});
}else {
console.info(CommonConstants.DATABASE_TAG, 'xx DatabaseUtils-createRdbStore 已經(jīng)存在!')
}
console.info(CommonConstants.DATABASE_TAG, 'xx DatabaseUtils-createRdbStore 結(jié)束...')
return globalThis.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, 'insertForm error ' + 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, 'insertValues error ' + JSON.stringify(error));
});
}
/**
* 更新成績到數(shù)據(jù)庫
* @param scoreData
* @param rdbStore
*/
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ù)。
*/
async sendNotifications(score: number) {}
}2. 卡片前端項目結(jié)構(gòu)圖。
EntryAbility.ets 程序入口初始化數(shù)據(jù)庫代碼如下:
onCreate(want, launchParam) {
// 數(shù)據(jù)庫初始化
globalThis.abilityWant = want;
globalThis.abilityParam = launchParam;
console.info(CommonConstants.ENTRY_ABILITY_TAG, 'xx onCreate 創(chuàng)建RDB數(shù)據(jù)庫')
// 創(chuàng)建RDB數(shù)據(jù)庫
DatabaseUtils.createRdbStore(this.context).then((rdbStore) => {
console.info(CommonConstants.ENTRY_ABILITY_TAG, 'xx onCreate RDB成功')
}).catch((error) => {
console.error(CommonConstants.ENTRY_ABILITY_TAG, 'xx onCreate 創(chuàng)建數(shù)據(jù)庫失敗:' + JSON.stringify(error))
Logger.error(CommonConstants.ENTRY_ABILITY_TAG, 'onCreate rdb error ' + JSON.stringify(error));
});
}EntryFormAbility.ets卡片生命周期代碼如下:
onAddForm(want) {
// 獲取卡片ID:ohos.extra.param.key.form_identity
let formId: string = want.parameters[CommonConstants.FORM_PARAM_IDENTITY_KEY] as string;
// 獲取卡片名稱:ohos.extra.param.key.form_name
let formName: string = want.parameters[CommonConstants.FORM_PARAM_NAME_KEY] as string;
// 獲取卡片規(guī)格:ohos.extra.param.key.form_dimension
let dimensionFlag: number = want.parameters[CommonConstants.FORM_PARAM_DIMENSION_KEY] as number;
console.info(CommonConstants.ENTRY_FORM_ABILITY_TAG, `xx 添加卡片是:${formId} ${dimensionFlag} ${dimensionFlag}`)
DatabaseUtils.createRdbStore(this.context).then((rdbStore) => {
// 卡片信息
let form: Form = new Form();
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, 'onAddForm rdb error ' + 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, 'xx onAddForm 更新卡片成功')
Logger.info(CommonConstants.ENTRY_FORM_ABILITY_TAG, 'refreshTime success ' + JSON.stringify(data));
}
});
// 返回初始化卡片數(shù)據(jù)
let formData: FormData = new FormData();
formData.formId = formId;
formData.bestScore = 0;
formData.matrixNum = '1x1';
formData.totalBestScore = 0;
return formBindingData.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%')
}
總結(jié)
通過開發(fā)這個小游戲元服務(wù),學(xué)習(xí)到不少知識,其實我有嘗試過把數(shù)據(jù)庫操作類寫到動態(tài)共享包里,這樣元服務(wù)打包后不就更小了,然而啟動后白屏了,進步問題,等華為相關(guān)技術(shù)人員回復(fù),想學(xué)習(xí)動態(tài)共享包的,可以參考關(guān)系型數(shù)據(jù)庫-動態(tài)共享包開發(fā), 總結(jié)這個項目用到以下知識點:
- 使用notification發(fā)布通知。
- 使用關(guān)系型數(shù)據(jù)庫插入、更新、刪除卡片數(shù)據(jù)。
- 使用FormExtensionAbility創(chuàng)建、更新、刪除元服務(wù)卡片。
想了解更多關(guān)于開源的內(nèi)容,請訪問:
開源基礎(chǔ)軟件社區(qū)
https://ost.
分享文章:游戲萬能卡片—舒爾特方格游戲
本文鏈接:http://m.fisionsoft.com.cn/article/djicche.html


咨詢
建站咨詢
