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

一、前言

作为一名开发爱好者,从大了讲,我学习并进行 HarmonyOS 相关开发是为了能为鸿蒙生态建设尽一份绵薄之力,从小了讲,就是为了自己的兴趣。而万能卡片是一个让我非常感兴趣的东西。

很多时候我跟别人解释什么是万能卡片,都会这么说:"万能卡片能实现让你在不用打开 app 的前提下,在桌面上就能使用到相关服务"。有一天,我的朋友跟我说,既然可以体验到各种服务,那么能直接在桌面上玩游戏吗?

通过对万能卡片相关文档的阅读,我认为想要实现一些简单的游戏应该没有问题,思考再三,我决定做一个井字棋小游戏,希望能给各位开发者提供些开发思路。

实现效果如下:

可以看到,在桌面上有一个 2x2 的小卡片,通过两名玩家轮流下棋的方式,进行井字棋的博弈,结局分为玩家 1 胜利、玩家 2 胜利或者平局,看似简单,但也实现了朋友提出来的"在桌面上玩游戏"的要求。

二、基本知识

想要学习这个项目的开发,首先我们要掌握以下几个知识:

  1. HUAWEI DevEco Studio 是开发工具,是华为基于 IDEA 开源版本打造的开发平台,支持页面预览、多端模拟等功能;

  2. ArkTS 是目前主推的开发语言,简洁的语法规则极大的减少了学习成本;

  3. 元服务是华为提出的一种新的概念,首先一个特点就是不用下载,即开即用;其次,元服务在手机上的表现形式,主要是万能卡片,通过与万能卡片的交互实现一些功能,也可以通过卡片作为类似于 app 的页面入口实现更多的功能;最后,既然是以万能卡片为入口的,其形式就具有多样化的特点,可以是 2x2,也可以是 1x2、2x4 或者 4x4。

三、项目创建

1. 建立项目

选择"Atomic Service"即建立一个元服务项目,点击"Next"。

2. 项目目录

这里有几个重要的文件,首先是 EntryAbility.ts,这个文件对应的是 UIAbility,通俗的理解就是,当用户想要通过与万能卡片的交互打开一个类似 app 页面的时候,那么打开的页面就可以看做是一个 UIAbility;接着是 EntryFromAbility.ts,这个是卡片的 Ability,可以做卡片的数据更新,或者与 UIAbility 相关的交互等;Index.ets 就是默认打开的页面了;而 WidgetCard.ets 则是卡片的页面;如果想要设置元服务的标题,可以在 AppScope/resources/base/element/string.json 中修改 value 的值。

3. 预览器

展开 Previewer,预览器中可以查看页面效果,其中 Default 尺寸与大部分手机的实际效果是相同的。可以方便的查看自己的 UI 代码写出来是什么效果,也可以测试交互代码,非常方便。

四、项目开发

以下操作均是在 WidgetCard.ets 中完成:

1. 绘制棋盘

棋盘的绘制分为三个部分:

首先是背景图,直接在 Column()上进行设置背景,代码为:

bash 复制代码
.backgroundImage($r('app.media.back'))
.backgroundImageSize(ImageSize.Cover)

接着通过循环渲染,利用 Flex 布局来绘制格子,这里用到了两个知识点:(1)自定义组件

这里的"gezi"就是一个自定义组件,传入 idx,num 这两个参数,再绑定上一个 click 事件。

(2)循环渲染

这里需要在棋盘里显示 9 个"gezi"组件,最简单的办法是写上 9 遍基本同样的代码,但是这样既不便于维护,也不美观,因此可以使用循环渲染的方法。

kotlin 复制代码
Flex({wrap:FlexWrap.Wrap}){
  ForEach(this.qipan,(item,idx)=>{
    gezi({
      idx:idx,
      num:item,
      click:()=>{
        if(!this.canplay)return;
        let n = this.qipan[idx];
        if(n > 0)return;
        this.qipan[idx] = this.shunxv;
        this.shunxv = this.shunxv == 1 ? 2 : 1;
        //检查
        this._Check();
      }
    })
  })
}.width(35*3)
.height(35*3)

然后创建下方的两个小图标,"刷新"用来重置棋盘,而"信息"用来点击进入小游戏的说明页。这里对于页面的跳转,使用的是 postCardAction 方法。

最后再绘制一个结果显示页面,使用条件渲染来控制是否显示,由于需要覆盖整个页面,因此采用了 position+zindex 的写法。

scss 复制代码
if(this.resshow){
  //这里绘制一个结果提示页面
  Column(){
    Text(this.res).fontSize(20).fontColor('white')
  }
  .backgroundColor('rgba(0,0,0,0.3)')
  .height('100%')
  .width('100%')
  .position({x:0,y:0})
  .zIndex(1)
  .alignItems(HorizontalAlign.Center)
  .justifyContent(FlexAlign.Center)
  .onClick(()=>{
    this._Init();
  })
}

最后效果如下:

2. 项目逻辑

井字棋的基本原理非常简单,就是在横、竖或者斜线上,同一类棋子排成三个即为胜利,而且整体只有 9 个格子,所以我们可以直接创建一个一维数组代表棋盘:

typescript 复制代码
@State qipan : Array<number> =
  [0,0,0,
   0,0,0,
   0,0,0]

0 代表这个格子没有落子,1 代表是"X",2 代表是"O",当玩家每次落子后,这个数组中相应的数字就会改变,同时渲染棋盘。

作为一个简单的小游戏,其胜利的情况是有限的几种,可以直接将其罗列出来:

css 复制代码
const win = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];

简单解释一下,比如第一个[0,1,2],指的就是,当棋盘数组的第 0 位、第 1 位和第 2 位,这三个数字相同时,说明有一个玩家胜出了。

每次落子后执行_Check 方法,对胜利的每一种情况进行循环,检查当前棋盘是否符合其中的任意一种胜利条件,当然还有一个条件,那就是要把 0 排除在胜利条件外,因为 0 代表的是没有落子。如果 9 个格子都填满了,却没有触发胜利条件的话,则视为平局。

五、总结

万能卡片的潜力实际上是非常巨大的,目前市面上我发现大部分的卡片主要用来进行信息的展示,还需要在"交互"或者"可玩性"上继续挖掘,希望这篇文章能给大家带来一点启发,期待出现更多好玩的万能卡片。

相关推荐
SameX1 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
Random_index9 小时前
#Uniapp篇:支持纯血鸿蒙&发布&适配&UIUI
uni-app·harmonyos
鸿蒙自习室12 小时前
鸿蒙多线程开发——线程间数据通信对象02
ui·harmonyos·鸿蒙
SuperHeroWu714 小时前
【HarmonyOS】鸿蒙应用接入微博分享
华为·harmonyos·鸿蒙·微博·微博分享·微博sdk集成·sdk集成
zhangjr057517 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
诗歌难吟4641 天前
初识ArkUI
harmonyos
SameX1 天前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
郭梧悠1 天前
HarmonyOS(57) UI性能优化
ui·性能优化·harmonyos
郝晨妤1 天前
鸿蒙原生应用开发元服务 元服务是什么?和App的关系?(保姆级步骤)
android·ios·华为od·华为·华为云·harmonyos·鸿蒙
Peace*1 天前
HarmonyOs鸿蒙开发实战(16)=>沉浸式效果第一种方案一窗口全屏布局方案
harmonyos·鸿蒙·鸿蒙系统