0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS 3.1上实现游戏万能卡片

OpenHarmony技术社区 来源:OST开源开发者 作者:OST开源开发者 2023-06-06 09:27 次阅读

舒尔特方格游戏,是注意力训练方法之一,可以帮助孩子纠正上课分心走神、回家做作业拖拉毛病,但不能贪玩哦,玩多了,对眼睛,视力不好。

①消息通知栏,通知用户当前最优成绩,也就是当前最快时间。

②元服务卡片,在桌面上添加 2x2 或 2x4 或 2x4 规格元服务卡片,能看到不同布局随机数字,根据左上角红色字提示,快速完成点击,用时最少为最优成绩。

③1x2 规格元服务卡片,只显示当前最优成绩,点击可以查看 2x2 或 2x4 或 2x4 规格元服务卡片最快用时游戏记录。

关系型数据库,用于查询,添加,更新,删除元服务卡片信息和各卡片游戏用时成绩数据。

效果图如下: 489ae7de-0408-11ee-90ce-dac502259ad0.gif

知识点

消息通知:提供通知管理的能力,包括发布、取消发布通知,创建、获取、移除通知通道,订阅、取消订阅通知,获取通知的使能状态、角标使能状态,获取通知的相关信息等。 关系型数据库:关系型数据库基于 SQLite 组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的 SQL 语句来满足复杂的场景需要。 元服务卡片开发:卡片是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达、减少体验层级的目的。 卡片提供方:显示卡片内容,控制卡片布局以及控件点击事件。 卡片使用方:显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。 卡片管理服务:用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。

软件要求:

DevEco Studio 版本:DevEco Studio 3.1 Release 及以上版本。

HarmonyOS SDK 版本:API version 9 及以上版本。

硬件要求:

设备类型:华为手机 3.1 系统或运行在 DevEco Studio 上的远程模拟器API9。

HarmonyOS 系统:3.1.0 Developer Release 及以上版本。

卡片讲解

1x2 卡片主要显示所有卡片最优成绩,也就是用时最少的,同时点击卡片,跳转到主界面,查看卡片游戏记录。

48e15a0c-0408-11ee-90ce-dac502259ad0.jpg

2x2 卡片显示的是 3x3 布局随机生成 1~9 数字,正上方标题显示挑战成功或失败提示,左上角红色字提示下一个要点击的数字按钮,右上角显示当次完成后用时和此卡片用时最少成绩。

当此次的用时少于最好用时,挑战成功,并更新数据库此卡片记录,如果此次用时大于最好用时,提示挑战失败,不用更新数据库。

48f1e0d4-0408-11ee-90ce-dac502259ad0.jpg

2x4 卡片显示的是 7x2 布局随机生成 1~14 数字,显示内容和游戏规则与 2x2 卡片一样。

490776c4-0408-11ee-90ce-dac502259ad0.jpg

4x4 卡片显示的是 6x6 布局随机生成 1~36 数字,显示内容和游戏规则与 2x2 卡片一样。

491924dc-0408-11ee-90ce-dac502259ad0.jpg

首次启动或点击 1x2 卡片进入到主界面,主界面显示各卡片游戏成绩记录。

49306872-0408-11ee-90ce-dac502259ad0.jpg

通知显示效果:

49507040-0408-11ee-90ce-dac502259ad0.jpg

代码讲解

数据库操作后端项目结构图:

49659092-0408-11ee-90ce-dac502259ad0.png

FormData.ets 实体类代码如下:

exportdefaultclassFormData{
//卡片ID
formId:string;
//距阵数3x3
matrixNum:string;
//最优成绩
bestScore:number;
//总最优成绩
totalBestScore:number;
}

Form.ets 数据库卡片表如下:

exportdefaultclassForm{
//卡片ID
formId:string;
//卡片名称
formName:string;
//卡片描述
dimension:number;
/**
*封装卡片数据
*@returns
*/
toValuesBucket(){
return{
'formId':this.formId,
'formName':this.formName,
'dimension':this.dimension
};
}
}

ScoreData.ets 游戏记录成绩表如下:

exportdefaultclassScoreData{
//卡片
formId:string;
//距阵数3x3
matrixNum:string;
//最优成绩
bestScore:number;
/**
*获取插入成绩记录数
*@returns
*/
toValuesBucket(){
return{
'formId':this.formId,
'matrixNum':this.matrixNum,
'bestScore':this.bestScore
};
}
}

DatabaseUtils.ets 数据库操作类部分代码如下:

exportclassDatabaseUtils{

/**
*创建RDB数据库
*
*@param{context}上下文
*@return{globalThis.rdbStore}returnrdbStoreRDB数据库
*/
asynccreateRdbStore(context:Context){
console.info(CommonConstants.DATABASE_TAG,'xxDatabaseUtils-createRdbStore开始...')
//如果全局变量rdbStore不存在,创建
if(!globalThis.rdbStore){
console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 新创建!')

awaitDataRdb.getRdbStore(context,CommonConstants.RDB_STORE_CONFIG)
.then((rdbStore)=>{
console.info(CommonConstants.DATABASE_TAG,'xxRDBStore回调')
if(rdbStore){
//创建卡片表
rdbStore.executeSql(CommonConstants.CREATE_TABLE_FORM).catch((error)=>{
console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 创建卡片表失败:'+JSON.stringify(error))
Logger.error(CommonConstants.DATABASE_TAG,'executeSqlFormerror'+JSON.stringify(error));
});
//创建成绩表
rdbStore.executeSql(CommonConstants.CREATE_TABLE_SCORE_DATA).catch((error)=>{
console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 创建成绩表失败:'+JSON.stringify(error))
Logger.error(CommonConstants.DATABASE_TAG,'executeSqlSensorerror'+JSON.stringify(error));
});
//存储RDBStore到全局变量
globalThis.rdbStore=rdbStore;
console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 创建成功!')
}
}).catch((error)=>{
console.error(CommonConstants.DATABASE_TAG,'xx DatabaseUtils 创建RDB数据库失败:'+JSON.stringify(error))
Logger.error(CommonConstants.DATABASE_TAG,'createRdbStoreerror'+JSON.stringify(error));
});
}else{
console.info(CommonConstants.DATABASE_TAG,'xx DatabaseUtils-createRdbStore 已经存在!')
}

console.info(CommonConstants.DATABASE_TAG,'xxDatabaseUtils-createRdbStore结束...')
returnglobalThis.rdbStore;
}

/**
*插入卡片数据。
*
*@param{Form}Form表单实体。
*@param{DataRdb.RdbStore}RDB存储RDB数据库。
*@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));
});
}

/**
*将成绩插入数据库。
*
*@param{ScoreData}scoreData。
*@param{DataRdb.RdbStore}RDB存储RDB数据库。
*/
insertValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){
rdbStore.insert(CommonConstants.TABLE_SCORE,scoreData.toValuesBucket()).catch((error)=>{
Logger.error(CommonConstants.DATABASE_TAG,'insertValueserror'+JSON.stringify(error));
});
}

/**
*更新成绩到数据库
*@paramscoreData
*@paramrdbStore
*/
updateValues(scoreData:ScoreData,rdbStore:DataRdb.RdbStore){}

/**
*删除卡片数据。
*
*@param{string}formId表单ID。
*@param{DataRdb.RdbStore}RDB存储RDB数据库。
*/
deleteFormData(formId:string,rdbStore:DataRdb.RdbStore){}

/**
*更新卡片
*
*@param{DataRdb.RdbStore}RDB存储RDB数据库。
*/
updateForms(rdbStore:DataRdb.RdbStore){}

/**
*发送通知
*
*@param{string}Steps显示的值步数。
*/
asyncsendNotifications(score:number){}

}

卡片前端项目结构图:

49800ada-0408-11ee-90ce-dac502259ad0.png

EntryAbility.ets 程序入口初始化数据库代码如下:

onCreate(want,launchParam){
//数据库初始化
globalThis.abilityWant=want;
globalThis.abilityParam=launchParam;
console.info(CommonConstants.ENTRY_ABILITY_TAG,'xxonCreate创建RDB数据库')
//创建RDB数据库
DatabaseUtils.createRdbStore(this.context).then((rdbStore)=>{
console.info(CommonConstants.ENTRY_ABILITY_TAG,'xxonCreateRDB成功')
}).catch((error)=>{
console.error(CommonConstants.ENTRY_ABILITY_TAG,'xx onCreate 创建数据库失败:'+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;
//获取卡片规格: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))
//保存卡片信息到数据库
DatabaseUtils.insertForm(form,rdbStore);
//获取最优成绩
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));
}
});

//返回初始化卡片数据
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}){
//循环显示数字按钮
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%')
}

总结

通过开发这个小游戏元服务,学习到不少知识,其实我有尝试过把数据库操作类写到动态共享包里,这样元服务打包后不就更小了,然而启动后白屏了,进步问题,等华为相关技术人员回复,想学习动态共享包的,可以参考关系型数据库-动态共享包开发。 总结这个项目用到以下知识点:

使用 notification 发布通知。

使用关系型数据库插入、更新、删除卡片数据。

使用 FormExtensionAbility 创建、更新、删除元服务卡片。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 华为
    +关注

    关注

    215

    文章

    33619

    浏览量

    247154
  • 游戏
    +关注

    关注

    2

    文章

    696

    浏览量

    26040
  • 数据库
    +关注

    关注

    7

    文章

    3591

    浏览量

    63369
  • HarmonyOS
    +关注

    关注

    79

    文章

    1838

    浏览量

    29261
  • OpenHarmony
    +关注

    关注

    23

    文章

    3295

    浏览量

    15159

原文标题:HarmonyOS 3.1上实现“游戏万能卡片”

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    HarmonyOS服务卡片跑AIGC

    我们认为基于 AIGC 能力类型的 HarmonyOS 元服务万能卡片应该通过 API 方式调用合规训练后的各具特色的模型与角色来服务用户,通过万能
    的头像 发表于 04-25 09:40 1751次阅读
    <b class='flag-5'>HarmonyOS</b>服务<b class='flag-5'>卡片</b>跑AIGC

    万能总线怎么焊接

    万能总线怎么焊接
    发表于 03-24 14:40

    电子万能试验机与液压万能试验机的区别

      电子万能材料试验机主要采用伺服电机作为动力源,丝杠、丝母作为执行部件,实现试验机移动横梁的速度控制。在传动控制,目前主要有两种形式,同步带 和减速机。国内来说,长春地区的试验机厂家多采用同步带
    发表于 07-04 16:06

    HarmonyOS万能服务卡片开发尝试历程(一)

    本系列帖子,会将我们对服务卡片的一个探索的过程进行总结,很多不完善的地方,欢迎批评讨论。非常早期的尝试,微、小、中、大卡整套,统一的色彩,纯图片的形式,纯图片的方式比较容易固定和兼容手机、平板和折叠屏;想通过万能服务卡片的方式,
    发表于 09-07 15:15

    HarmonyOS万能服务卡片开发尝试历程(二)

    对人物、景点等,进行图文结合描述的方式进行尝试。希望用户通过一张服务卡片,可以比较完整地了解一位人物的主要特征,一个景点的主要特色。服务卡片的内容,还是固定的,主要是起到核心内容展示与引导点击的尝试。
    发表于 09-08 15:14

    李洋:手把手教你开发一个元服务万能卡片

    万能卡片概念与优势元服务基于HarmonyOS API开发,秉承着HarmonyOS系统一次开发多端部署、可分可合自由流转、统一生态原生智能的三大应用与服务开发理念,支持运行在1+8
    发表于 03-20 14:37

    HarmonyOS元服务万能卡片训练一下文心一言的AIGC能力

    服务与万能卡片。我们认为基于AIGC能力类型的HarmonyOS元服务万能卡片应该通过API方式调用合规训练后的各具特色的模型与角色来服务用
    发表于 04-18 10:31

    HarmonyOS元服务开发实践:桌面卡片字典

    等功能。 二、元服务效果 万能卡片效果 2.元服务内页 三、项目开发 环境搭建 软件要求: DevEco Studio版本:DevEco Studio 3.1 Release及以上版本
    发表于 08-24 16:55

    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Badge

    : 12 }) }.width(\'100%\').backgroundColor(\'#F1F3F5\').padding({ bottom: 12 }) }.width(\'100%\') } } 五、场景 卡片和服务页面上没有执行的内容的提示。 本文根据
    发表于 09-28 11:53

    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Span

    }) } }.width(\'100%\').height(250).padding({ left: 35, right: 35, top: 35 }) 五、场景 适合做文本特效的各种卡片。 本文根据HarmonyOS官方文档整理。
    发表于 10-07 17:50

    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Stack

    (Alignment.Top) }.width(\'100%\').height(150).margin({ top: 5 }) } } 四、效果展示 五、场景 卡片实现堆叠的场景使用。 本文根据
    发表于 10-09 14:29

    HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Radio

    ) }) } }.padding({ top: 30 }) } } 复制 五、效果 六、场景 适合卡片直接操作单选项的场景。 本文根据HarmonyOS官方文档整理。
    发表于 10-13 17:21

    HarmonyOS开发案例分享:万能卡片也能用来玩游戏

    直接在桌面上玩游戏吗? 通过对万能卡片相关文档的阅读,我认为想要实现一些简单的游戏应该没有问题,思考再三,我决定做一个井字棋小
    发表于 12-01 09:35

    HarmonyOS 3.1实现计步卡片

    本篇帖子是参考 Codelab 基于 Stage 模型 JS 服务卡片,使用最新 ArkTS 元服务开发的,实现带有卡片的计步应用,用于介绍卡片的开发及生命周期
    的头像 发表于 05-29 11:10 499次阅读

    开发案例分享:万能卡片也能用来玩游戏

    ,从大了讲,我学习并进行HarmonyOS相关开发是为了能为鸿蒙生态建设尽一份绵薄之力,从小了讲,就是为了自己的兴趣。 而万能卡片是一个让我非常感兴趣的东西。 很多时候我跟别人解释什么是万能
    的头像 发表于 12-15 16:35 221次阅读
    开发案例分享:<b class='flag-5'>万能</b><b class='flag-5'>卡片</b>也能用来玩<b class='flag-5'>游戏</b>