一个简单鸿蒙游戏的完整代码拆解
本文介绍了鸿蒙小游戏开发的核心架构设计。作者展菲提出四层结构:状态层(Store)、系统层(System)、UI层和入口层,通过一个简单的战斗游戏案例展示了如何实现代码组织。Store集中管理游戏状态,System处理游戏规则和循环调度,UI层专注展示和交互,入口层负责初始化。这种架构避免了传统开发中UI与逻辑混杂的问题,支持多端扩展和功能增强。文章强调鸿蒙游戏开发的本质是构建"跨设备的

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
文章目录
引言
当项目从 Demo 变成“稍微像个游戏”的时候:
文件开始变多
逻辑开始混乱
状态开始失控
今天我们主要讲:
把一个“完整但简单”的鸿蒙小游戏,彻底拆开讲清楚
目标是让你真正理解:
一个 ArkUI 游戏项目,到底应该怎么组织
一、我们要实现什么?
游戏目标:简单战斗点击游戏
规则:
点击攻击 → 敌人掉血
敌人自动攻击 → 玩家掉血
血量为 0 → 游戏结束
核心元素:
玩家 HP
敌人 HP
攻击行为
游戏状态(进行中 / 结束)
二、最终结构
我们先看“正确结构”,再逐层拆:
/game
├── store/
│ └── GameStore.ts
├── system/
│ └── BattleSystem.ts
├── ui/
│ └── GamePage.ets
└── main.ets
核心思想:
状态(store)
逻辑(system)
UI(ui)
入口(main)
这四层,缺一不可。
三、第一层:状态层
为什么必须有 Store?
如果你把所有状态写在 UI 里:
@State hp
@State enemyHp
结果就是:
页面 = 状态中心 = 逻辑中心
直接爆炸。
正确写法
// store/GameStore.ts
export class GameStore {
playerHp: number = 100
enemyHp: number = 100
isGameOver: boolean = false
attackEnemy() {
if (this.isGameOver) return
this.enemyHp -= 10
if (this.enemyHp <= 0) {
this.enemyHp = 0
this.isGameOver = true
}
}
takeDamage() {
if (this.isGameOver) return
this.playerHp -= 5
if (this.playerHp <= 0) {
this.playerHp = 0
this.isGameOver = true
}
}
reset() {
this.playerHp = 100
this.enemyHp = 100
this.isGameOver = false
}
}
export const store = new GameStore()
这一层解决什么问题?
状态集中
逻辑内聚
可复用
可跨设备(未来)
一句话总结:
Store = 游戏的“唯一真实世界”
四、第二层:系统层
很多人会问:
Store 已经有逻辑了,为什么还要 System?
因为:
Store → 状态 + 基本操作
System → 游戏规则 / 调度 / 循环
示例:战斗系统
// system/BattleSystem.ts
import { GameStore } from '../store/GameStore'
export class BattleSystem {
start(store: GameStore) {
setInterval(() => {
this.update(store)
}, 1000)
}
update(store: GameStore) {
if (store.isGameOver) return
store.takeDamage()
}
}
这一层的意义
把“游戏运行机制”抽出来
避免 UI / Store 变复杂
你可以继续扩展:
AI 系统
掉落系统
关卡系统
五、第三层:UI 层
终于到 ArkUI 的核心了。
但注意一个原则:
UI 不写复杂逻辑,只做“状态展示 + 触发行为”
页面代码
// ui/GamePage.ets
import { store } from '../store/GameStore'
@Entry
@Component
struct GamePage {
build() {
Column() {
Text(`玩家 HP: ${store.playerHp}`)
.fontSize(20)
Text(`敌人 HP: ${store.enemyHp}`)
.fontSize(20)
if (store.isGameOver) {
Text("游戏结束")
.fontSize(30)
}
Button("攻击")
.onClick(() => {
store.attackEnemy()
})
Button("重开")
.onClick(() => {
store.reset()
})
}
}
}
关键理解
这里没有:
手动刷新 UI
render()
draw()
因为:
ArkUI 自动根据状态更新 UI
你只做一件事:
改状态
六、第四层:入口
// main.ets
import { BattleSystem } from './system/BattleSystem'
import { store } from './store/GameStore'
const battleSystem = new BattleSystem()
battleSystem.start(store)
这里做了什么?
启动游戏循环
连接 Store 和 System
七、完整运行流程
把整个链路串起来:
点击按钮
↓
store.attackEnemy()
↓
状态变化(enemyHp)
↓
ArkUI 自动刷新 UI
同时:
BattleSystem 定时执行
↓
store.takeDamage()
↓
状态变化(playerHp)
↓
UI 自动更新
八、这个结构解决了什么问题?
1、不会再“写乱”
因为:
UI ≠ 状态 ≠ 系统
2、可以扩展
你可以轻松加:
关卡系统
装备系统
技能系统
3、支持多端
因为:
状态在 Store
UI 可多份
天然支持:
手机 + TV 同步
九、常见错误对比
错误写法
@State hp
@State enemyHp
setInterval(...)
onClick(...)
问题:
页面膨胀
逻辑混乱
无法扩展
正确写法
Store → 状态
System → 规则
UI → 展示
十、你现在应该建立的“脑模型”
写鸿蒙游戏时,你脑子里应该是:
1、有一个“世界”(Store)
2、有一套“规则”(System)
3、有多个“观察者”(UI)
而不是:
我在写一个页面
总结
一个简单鸿蒙游戏的完整结构,本质是:
状态中心(Store)
+ 规则系统(System)
+ UI 渲染(ArkUI)
你真正写的不是:
一个页面
而是:
一个“可被 UI 渲染的状态系统”
结合前几篇的所有结论:
状态驱动
多端协同
无设备边界
最终统一成一句话:
鸿蒙游戏开发,本质是在构建一个“跨设备的状态系统 + UI 映射层”。
更多推荐


所有评论(0)