

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)
大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向: 前端 / 跨端 / 小程序 / 移动端工程化 内容平台: 掘金、知乎、CSDN、简书 创作特点: 实战导向、源码拆解、少空谈多落地 **文章状态:**长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在"API 怎么用",而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源 (工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学"明白",也用"到位"
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
-
- 引言
- 一、当游戏复杂后
- [二、为什么 Store 会失控?](#二、为什么 Store 会失控?)
- 三、正确拆分的第一原则:职责单一
-
- [Store 负责:](#Store 负责:)
- [System 负责:](#System 负责:)
- [四、第一步:让 Store "变傻"](#四、第一步:让 Store “变傻”)
- [五、第二步:让 System "变强"](#五、第二步:让 System “变强”)
- [六、第三步:按"领域"拆 System](#六、第三步:按“领域”拆 System)
-
- 示例结构
- [每个 System 只做一件事](#每个 System 只做一件事)
- 示例:LevelSystem
- 七、第四步:引入"调度层"
- [八、第五步:避免"System 互相调用"](#八、第五步:避免“System 互相调用”)
- 九、最终架构
- 十、这一套架构解决了什么?
- 十一、开发者常见误区
-
- [误区 1:Store 写满逻辑](#误区 1:Store 写满逻辑)
- [误区 2:System 持有状态](#误区 2:System 持有状态)
- [误区 3:UI 写业务逻辑](#误区 3:UI 写业务逻辑)
- 十二、一个关键认知升级
- 总结
引言
鸿蒙小游戏结构:
Store(状态)
System(规则)
UI(展示)
刚开始你会觉得:
很清晰,很优雅
但只要你把游戏复杂度往上提一点,比如:
加技能
加关卡
加掉落
加 AI
很快就会出现一个典型问题:
Store 开始膨胀,System 开始混乱
你会看到这样的代码:
GameStore:1000 行
BattleSystem:到处依赖
UI:开始写逻辑补丁
这时候很多人会误以为:
是不是 ArkUI 不适合做复杂游戏?
其实不是,问题只有一个:
你还在用"初级架构"承载"复杂系统"
所以我们需要解决一个关键问题:
鸿蒙游戏架构进阶:如何拆分 Store 与 System?
一、当游戏复杂后
你必须做三件事:
1、Store:只存状态,不写复杂逻辑
2、System:只写规则,不持有状态
3、按"领域"拆分,而不是按"文件"拆分
如果你只记一句话:
Store 是"数据层",System 是"行为层"
二、为什么 Store 会失控?
先看一个"真实会发生"的代码:
ts
class GameStore {
playerHp = 100
enemyHp = 100
level = 1
exp = 0
gold = 0
attack() { ... }
levelUp() { ... }
dropItem() { ... }
enemyAI() { ... }
}
问题在哪里?
状态 + 逻辑 + AI + 掉落 全在一起
这本质上是:
把整个游戏塞进了一个类
结果就是:
不可维护
不可扩展
不可复用
三、正确拆分的第一原则:职责单一
我们先把职责拆开:
Store 负责:
保存状态
提供基础读写
System 负责:
修改状态
执行规则
驱动流程
四、第一步:让 Store "变傻"
原来的写法
ts
attackEnemy() {
this.enemyHp -= 10
}
改造后
ts
class GameStore {
playerHp = 100
enemyHp = 100
}
Store 只剩:
纯数据
你可能会不适应:
"那逻辑去哪了?"
答案是:
全部移到 System
五、第二步:让 System "变强"
战斗系统拆分
ts
// system/BattleSystem.ts
import { GameStore } from '../store/GameStore'
export class BattleSystem {
attack(store: GameStore) {
store.enemyHp -= 10
if (store.enemyHp <= 0) {
store.enemyHp = 0
}
}
takeDamage(store: GameStore) {
store.playerHp -= 5
if (store.playerHp <= 0) {
store.playerHp = 0
}
}
}
关键变化
System 不持有状态
只操作传入的 Store
这带来一个巨大好处:
System 是"无状态的",可以复用、测试、组合
六、第三步:按"领域"拆 System
当系统继续变大时,不能再只有一个:
BattleSystem
你必须按"领域"拆分。
示例结构
/system
├── BattleSystem.ts
├── LevelSystem.ts
├── DropSystem.ts
├── AISystem.ts
每个 System 只做一件事
BattleSystem
处理战斗
LevelSystem
处理升级
DropSystem
处理掉落
示例:LevelSystem
ts
export class LevelSystem {
addExp(store: GameStore, exp: number) {
store.exp += exp
if (store.exp >= 100) {
store.level += 1
store.exp = 0
}
}
}
七、第四步:引入"调度层"
当 System 变多后,会出现一个问题:
谁来控制执行顺序?
你不能在 UI 里写:
battle.attack()
level.addExp()
drop.roll()
否则 UI 又变复杂。
正确做法:GameEngine
ts
class GameEngine {
battle = new BattleSystem()
level = new LevelSystem()
update(store: GameStore) {
this.battle.takeDamage(store)
this.level.addExp(store, 1)
}
}
游戏循环
ts
setInterval(() => {
engine.update(store)
}, 16)
这一层的意义
统一调度
控制顺序
隔离 UI
八、第五步:避免"System 互相调用"
一个常见错误:
ts
BattleSystem → 调 LevelSystem
LevelSystem → 调 DropSystem
最后变成:
系统互相耦合
正确方式
全部交给:
GameEngine 调度
九、最终架构
┌──────────────┐
│ GameStore │
└──────┬───────┘
│
┌─────────┼─────────┐
│ │ │
Battle Level Drop
System System System
\ | /
\ | /
└── GameEngine ┘
│
UI
十、这一套架构解决了什么?
1、复杂度可控
每个 System 独立
2、可扩展
你可以随时加:
任务系统
技能系统
背包系统
3、可测试
ts
battle.attack(mockStore)
不需要 UI。
4、多端天然支持
因为:
Store 是唯一状态源
System 是纯逻辑
UI 可多个
十一、开发者常见误区
误区 1:Store 写满逻辑
结果:
变成 God Object(上帝类)
误区 2:System 持有状态
ts
this.store = store
问题:
生命周期混乱
多端难同步
误区 3:UI 写业务逻辑
结果:
不可维护
无法复用
十二、一个关键认知升级
初级阶段你会觉得:
我在写"游戏代码"
但进阶之后你会发现:
你在写的是一个"状态变换系统"
结构变成:
输入(点击 / AI)
↓
System(规则)
↓
Store(状态变化)
↓
UI(自动渲染)
总结
当鸿蒙游戏变复杂时,正确的拆分方式是:
Store:只存数据
System:只写规则
Engine:负责调度
UI:只做展示
最终统一为:
鸿蒙游戏的本质,是一个"由 System 驱动的状态演化系统"。