鸿蒙 ArkTS 实战:Shadow Match 从儿童影子配对到交互闭环完整解析

前言

Shadow Match 是一个基于鸿蒙 ArkTS 编写的单页互动应用,核心围绕 物体选择、影子匹配、儿童模式和奖励反馈 展开。项目没有依赖复杂服务端,也没有把逻辑拆散到多个页面,而是把状态、交互和结果反馈集中在 Index.ets 中完成。

本文直接根据项目源码写作,重点拆解它如何设计状态、如何触发用户操作、如何刷新 UI,以及如何继续扩展成更完整的小游戏或学习工具。文章可直接作为技术博客发布。

这类项目适合用来练习 ArkTS 声明式 UI:每一次点击都改变状态,每一次状态变化都反映到界面上。

在这里插入图片描述

上图可作为技术文章配图。实际发布时,也可以替换成项目运行截图,重点展示标题区、交互区、状态反馈区和结果区。

一、项目定位与用户场景

1.1 应用定位

应用用 MatchItem 保存物体、影子和匹配状态,先选物体再选影子,匹配成功后显示奖励文案。

这个项目的目标很明确:先建立一个能跑通交互流程的页面,再把具体玩法逐步接入。这样的路线适合小型鸿蒙应用快速成型。

1.2 目标用户

用户 使用目的 关注点
鸿蒙初学者 学习 ArkTS 状态与组件 状态流转清晰
小游戏开发者 快速验证玩法原型 点击反馈明确
教育工具作者 搭建训练和记录页面 结果可视化
产品原型设计者 验证低成本交互 页面结构简单

二、源码入口与页面骨架

2.1 入口组件

项目主页面使用 @Entry@Component 声明入口组件。

@Entry
@Component
struct Index {
  build() {
    Scroll() {
      Column({ space: 16 }) {
        Text('Shadow Match')
      }
    }
  }
}

2.2 页面分层

页面通常可以拆成四层:

  • 标题层:展示 Shadow Match
  • 状态层:展示分数、进度、结果或提示。
  • 交互层:承接按钮、输入框、网格或列表。
  • 反馈层:告诉用户操作是否成功。

这种结构可读性强,后续扩展时也容易定位代码。

三、核心数据模型

3.1 模型定义

本项目的核心模型可以抽象为 MatchItem

interface MatchItem {
  id: number;
  objectName: string;
  shadowName: string;
  matched: boolean;
}

3.2 模型作用

模型 作用 适用区域
MatchItem 保存核心交互对象 页面逻辑
状态字段 保存当前 UI 状态 @State
派生结果 计算分数、进度或提示 反馈区

模型先行 能降低 UI 复杂度。只要模型字段稳定,按钮、列表、网格和提示文案都可以围绕它组织。

四、状态字段设计

4.1 状态代码

项目用 @State 保存页面动态数据。

@State selectedObject: string = '';
@State reward: string = 'Pick an object, then pick its shadow.';
@State kidsMode: boolean = true;

4.2 状态表

状态 类型 职责
selectedObject 页面状态 参与 儿童影子配对 的交互闭环
reward 页面状态 参与 儿童影子配对 的交互闭环
kidsMode 页面状态 参与 儿童影子配对 的交互闭环
matches 页面状态 参与 儿童影子配对 的交互闭环

这些状态字段覆盖了 儿童影子配对 的主要交互路径。用户点击或输入后,状态变化会推动界面刷新。

五、默认数据与初始体验

5.1 默认内容

项目启动时不是空白页面,而是带有可理解的默认内容。

默认项 数值或编号 说明
Cup 1 Cup shadow
Ball 2 Ball shadow

5.2 为什么需要默认内容

默认内容能降低用户理解成本:

  1. 进入页面后立刻知道功能是什么。
  2. 可以直接测试按钮和状态变化。
  3. 方便开发者验证 UI 布局。

对于 儿童影子配对 来说,默认数据也是一组最小演示用例。

六、核心逻辑拆解

6.1 主要交互函数

核心交互集中在下面这段逻辑中。

pairShadow(item: MatchItem): void {
  if (this.selectedObject === '') {
    this.reward = 'Choose an object first.';
    return;
  }
  if (this.selectedObject === item.objectName) {
    this.reward = 'Reward animation: star unlocked for ' + item.objectName + '.';
  } else {
    this.reward = this.kidsMode ? 'Try again. Compare the outline.' : 'Mismatch.';
  }
  this.selectedObject = '';
}

6.2 逻辑路径

  1. 选择物体
  2. 点击影子
  3. 判断名称是否匹配
  4. 更新奖励或提示

这条路径覆盖了从用户操作到状态更新的完整过程。它不是静态展示页,而是一个能持续响应用户输入的交互页面。

七、辅助逻辑与状态刷新

7.1 辅助代码

项目中还包含辅助函数或状态刷新逻辑。

doneCount(): number {
  return this.matches.filter((item: MatchItem) => item.matched).length;
}

7.2 刷新策略

策略 代码表现 作用
修改状态 更新 @State 字段 触发 UI 刷新
重建数组 map 或新数组赋值 保证列表感知变化
文案反馈 更新提示字符串 告诉用户结果
分数记录 更新数值状态 形成可视化结果

在 ArkTS 页面里,状态刷新要比命令式操作更重要。代码写得越接近数据流,后续维护越容易。

八、交互组件设计

8.1 常见组件

项目根据玩法使用了按钮、输入框、网格、列表或开关。

Column({ space: 16 }) {
  Text('Shadow Match')
  Text('Status area')
  Button('Primary Action')
  Text('Feedback text')
}

8.2 组件职责

组件 作用 在本项目中的价值
Text 展示标题、结果和反馈 信息呈现
Button 触发主要动作 用户操作入口
TextInput 接收用户输入 表单型交互
ForEach 渲染数组数据 列表或网格
Grid/Row/Column 组织布局 控制视觉层级

组件选择应当服务业务,而不是堆砌控件。Shadow Match 的组件组合刚好覆盖当前玩法需要。

九、功能标签与业务能力

9.1 能力标签

序号 标签 说明
1 Object select 入口能力
2 Shadow choice 核心交互
3 Kids mode 反馈机制
4 Reward animation 扩展沉淀

9.2 业务含义

这些标签对应源码中的真实交互,不是装饰文案。比如 Object select 表示入口能力,Shadow choice 表示核心操作,Kids modeReward animation 则对应反馈与沉淀。

十、结果反馈设计

10.1 反馈文案

项目通过状态文本告诉用户当前结果。

@State feedbackText: string = 'Ready';

function updateFeedback(success: boolean): string {
  return success ? 'Action accepted.' : 'Try another choice.';
}

10.2 反馈原则

结果反馈需要做到三点:

  • 操作后立即变化。
  • 成功和失败文案区分明确。
  • 状态文本能指导下一步。

这对 儿童影子配对 很重要,因为用户需要根据反馈继续选择、输入或重新尝试。

十一、布局与视觉层次

11.1 页面容器

外层使用 Scroll 可以兼容内容增长。

Scroll() {
  Column({ space: 16 }) {
    Text('Shadow Match')
    // interactive content
  }
  .padding(20)
  .width('100%')
}
.height('100%')

11.2 视觉层次

层级 内容 设计目的
第一层 标题和主要指标 快速识别页面
第二层 输入或点击区域 承接核心交互
第三层 结果反馈 提醒下一步
第四层 重置、下一关或扩展按钮 完成闭环

十二、手工验证流程

12.1 验证步骤

可以按下面流程验证当前项目:

  1. 打开页面,确认标题为 Shadow Match
  2. 观察默认状态是否与源码一致。
  3. 执行一次主要交互。
  4. 查看状态文案、数值或选中态是否变化。
  5. 执行重置、下一关或辅助动作,确认页面能继续使用。
// 手工验证伪代码
const before = 'initial state';
const action = 'tap primary control';
const after = 'state changed';
console.info(before + ' -> ' + action + ' -> ' + after);

12.2 验证重点

验证项 预期
初始状态 能直接理解页面用途
主操作 有明确反馈
错误路径 不会破坏状态
重复操作 页面仍可继续
数据展示 与状态字段一致

十三、扩展为完整产品

13.1 业务扩展

后续可以加入图片素材、拖拽配对、星星动画、分龄难度和完成页。

13.2 工程扩展

可以把玩法结果抽象为统一结果对象,再由页面负责展示。

interface PlayResult {
  title: string;
  value: number;
  message: string;
  success: boolean;
}

function buildResult(title: string, value: number, message: string): PlayResult {
  return {
    title,
    value,
    message,
    success: value >= 0
  };
}

这种方式可以避免玩法逻辑和 UI 逻辑互相缠绕。

十四、性能与维护要点

14.1 状态数量控制

小型页面不需要引入复杂状态库,但要保证每个状态都有明确职责。无用状态越少,问题定位越快。

14.2 列表更新方式

涉及数组时,推荐使用 map 或新数组赋值。

const nextItems = oldItems.map((item) => {
  return item;
});

这能让页面更稳定地感知数据变化。

14.3 文案维护

反馈文案最好集中管理。后续如果要做多语言或无障碍读屏,集中管理会更容易。

十五、工程复盘

15.1 当前实现亮点

  • 使用 @State 驱动页面。
  • 主交互路径短,用户反馈明确。
  • 数据模型与 UI 展示关系清楚。
  • 页面结构适合继续扩展。
  • 代码适合初学者阅读和二次开发。

15.2 可复用经验

Shadow Match 的实现方式可以迁移到很多轻量互动项目:答题、训练、配对、点击反应、计分工具、儿童学习和家庭游戏。关键不是一次写完所有功能,而是先让状态流、交互流和反馈流闭合。

总结

Shadow Match 用鸿蒙 ArkTS 实现了一个围绕 儿童影子配对 的完整交互原型。它通过 MatchItem 或对应状态保存核心数据,用按钮、输入框、列表或网格承接操作,再用提示文本、分数和进度把结果展示出来。

从工程角度看,这个项目的价值在于清晰:状态字段明确,函数职责集中,UI 层级直接。后续继续接入真实素材、动画、持久化或排行榜,都可以沿着当前结构自然扩展。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。

补充说明:当前实现保持了单页结构,便于快速定位每一次状态变化。
补充说明:主要交互函数直接服务页面动作,适合继续拆分成独立业务模块。
补充说明:反馈文本是用户理解页面状态的关键,后续可以继续细化成功、失败和等待状态。
补充说明:如果增加持久化,建议先保存核心状态,再考虑保存视觉层配置。


相关资源:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐