鸿蒙 ArkTS 实战:Canvas 向量绘制 + @StorageLink 打造纯端侧翻牌记忆游戏
很多开发者入门 HarmonyOS 应用开发时,习惯从待办清单做起,但待办清单里几乎都是列表渲染与增删改查,很难覆盖动画、Canvas 绘制、状态跨页同步、持久化这些更能体现 ArkUI 能力的点。HarmonyOS-APP-memory-card-game 案例反其道而行:以点击翻牌、配对消除的经典玩法为输入,把全部逻辑与渲染收拢在设备本地,最终产出一个纯端侧、无云端依赖、无账号体系、无网络请求的完整 App。麻雀虽小,五脏俱全。
一、整体架构:三层拆分
工程只有三类文件,职责边界清晰:model 层负责牌堆生成、洗牌、翻开与配对状态流转,不接触任何 UI 组件;view 层负责牌面渲染、翻牌动画、结算弹窗;entry 页只做状态装配与页面跳转,通过 @StorageLink 拿到全局游戏状态。这样拆分的好处是游戏规则可以脱离 UI 单独验证,UI 改动也不会污染状态机。
二、Canvas 向量绘制:不依赖任何图片素材
案例最有意思的一点是牌面完全不使用图片:6 种几何形状 × 8 种高对比颜色,全部由 Canvas 向量路径实时生成。核心思路是把形状抽成一个绘制函数,入参是几何类型与颜色:
private drawShape(ctx: CanvasRenderingContext2D, kind: number, color: string, r: number) {
ctx.fillStyle = color;
ctx.beginPath();
switch (kind) {
case 0: // 圆形
ctx.arc(0, 0, r, 0, Math.PI * 2);
break;
case 1: // 三角
ctx.moveTo(0, -r);
ctx.lineTo(r * 0.866, r * 0.5);
ctx.lineTo(-r * 0.866, r * 0.5);
ctx.closePath();
break;
default: // 多边形
for (let i = 0; i < kind; i++) {
const a = (Math.PI * 2 * i) / kind - Math.PI / 2;
const px = Math.cos(a) * r;
const py = Math.sin(a) * r;
i === 0 ? ctx.moveTo(px, py) : ctx.lineTo(px, py);
}
ctx.closePath();
}
ctx.fill();
}
这样做有三个收益:安装包体积几乎不增加;任意分辨率下都清晰不糊;配色与形状随时可调,做无障碍适配也更容易,色盲用户可依赖形状区分。实践中有两个坑:Canvas 的 onReady 回调里必须按组件实际尺寸换算像素比,否则高分屏会发虚;重绘要按帧节流,避免动画期间每帧重建全部牌面。
三、3D 翻牌:rotate 与 animation 的最小实现
翻牌动效没有引入任何三方动画库,只用属性 rotate 配合 animation:
Text('')
.width(this.cardW)
.height(this.cardH)
.rotate({ y: this.flipped ? 180 : 0, centerX: '50%', centerY: '50%' })
.animation({ duration: 300, curve: Curves.easeInOut })
经验是 duration 控制在 250 到 350 毫秒之间手感最好,同时在翻转过程中切换正反面内容,用条件渲染或透明度过渡,避免出现翻到一半看到背面内容的穿帮。
四、@StorageLink:跨页状态同步的省心方案
游戏状态(关卡、得分、最佳记录)需要被多个页面共享,案例直接使用 @StorageLink 而不是层层传参:
@StorageLink('gameState') gameState: GameState = new GameState();
与 @State 相比,@StorageLink 天然具备跨页面、跨组件的能力,写入即全局可见;再配合 Preferences 落盘,重启应用后最佳成绩依然保留。这里有一个容易踩的坑:绑定的对象如果整体替换,会触发整树刷新,动画可能被打断;更稳妥的做法是只修改对象内部字段,让框架做细粒度更新。
五、TransitionEffect:结算弹窗的入场
结算弹窗使用 TransitionEffect 做入场与退场,把透明度与缩放组合起来,再挂上动画时长。要注意为节点加延迟销毁,等动画跑完再移除,否则会出现弹窗瞬间消失、动画看不到的情况。
六、纯端侧带来的取舍
没有网络、没有账号,意味着不需要处理登录态,不用考虑接口超时与重试,工程复杂度大幅下降;代价是所有数据都在本机,做排行榜、跨设备同步这类需求时要额外设计。对于练习 ArkUI 基本功、验证交互与动画方案来说,纯端侧是非常合适的起点。
七、小结
这个案例覆盖了 ArkTS 日常开发的绝大多数场景:Canvas 向量绘制、属性动画、跨页状态同步、本地持久化、@Builder 组件复用。如果你也在准备鸿蒙相关实践任务,建议直接把这个仓库拉下来跑一遍,再按自己的需求改造牌面与规则,收获会比看十篇教程都实在。项目地址可在鸿蒙实践中心的案例列表中检索 memory-card-game 找到。
- 点赞
- 收藏
- 关注作者
评论(0)