State 驱动鸿蒙游戏架构详解
本文介绍了在HarmonyOS(ArkUI)中开发游戏时采用状态驱动(State-Driven)架构的核心思想与实践方法。传统游戏开发的Game Loop模式(如setInterval更新渲染)在鸿蒙生态中难以维护,作者提出应转向"状态变化驱动UI"的范式。 文章通过对比传统写法与状态驱动写法的差异,阐述了状态驱动架构的核心优势:UI与逻辑解耦、更易维护、天然支持多端协同和AI


大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。
我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。
技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:掘金、知乎、CSDN、简书
创作特点:实战导向、源码拆解、少空谈多落地
文章状态:长期稳定更新,大量原创输出
我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。
子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”
持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱
文章目录
引言
如果你是从传统游戏开发(Unity / Cocos / 原生引擎)转到 HarmonyOS,很容易踩一个坑:
还在用“Game Loop 思维”写游戏
比如:
setInterval(() => {
update()
render()
}, 16)
这在传统引擎里是标准写法,但在鸿蒙(ArkUI)里,会越来越难维护。
原因只有一个:
鸿蒙的核心不是“帧驱动”,而是“State 驱动”
一、什么是 State 驱动?
一句话定义:
游戏的一切变化,本质都是“状态变化”
传统写法
function movePlayer() {
player.x += 10
renderPlayer()
}
State 驱动写法
gameStore.update({
player: {
...gameStore.state.player,
x: gameStore.state.player.x + 10
}
})
UI 不需要你管:
状态变 → UI 自动更新
二、核心架构
State 驱动游戏的结构:
输入(Input)
↓
Service(逻辑)
↓
Store(状态)
↓
UI(渲染)
可扩展为:
Agent(AI)
↓
Store
核心思想:
所有变化必须经过 Store
三、最小可运行模型
1、数据模型
// models/GameModel.ets
export interface GameState {
player: { x: number; y: number }
score: number
}
2、Store
// store/GameStore.ets
export class GameStore {
state: GameState = {
player: { x: 0, y: 0 },
score: 0
}
update(partial: Partial<GameState>) {
this.state = { ...this.state, ...partial }
this.notify()
}
notify() {
// 通知 UI(ArkUI 自动处理)
}
}
export const gameStore = new GameStore()
核心:
唯一数据源(Single Source of Truth)
3、Service
// services/GameService.ets
import { gameStore } from '../store/GameStore'
export class GameService {
moveRight() {
const { player } = gameStore.state
gameStore.update({
player: {
...player,
x: player.x + 10
}
})
}
addScore() {
gameStore.update({
score: gameStore.state.score + 1
})
}
}
export const gameService = new GameService()
原则:
逻辑只改状态
不操作 UI
4、UI(ArkUI)
@Entry
@Component
struct GamePage {
@State state = gameStore.state
build() {
Column() {
Image("player.png")
.position({
x: this.state.player.x,
y: this.state.player.y
})
Text(`Score: ${this.state.score}`)
Button("→")
.onClick(() => gameService.moveRight())
}
}
}
UI 只做一件事:
读取状态并展示
四、为什么比 Game Loop 更适合鸿蒙?
1、UI 与渲染解耦
Game Loop
update + render 手动控制
State 驱动
update → 状态 → UI 自动渲染
更符合 ArkUI。
2、更容易维护
Game Loop 问题
- 状态分散
- 渲染难控
- Bug 难查
State 驱动
所有变化都在 Store
Debug 非常清晰。
3、天然支持多端
distributedSync.send(gameStore.state)
同一状态可以:
- 手机控制
- TV 渲染
- 平板辅助
Game Loop 很难做到这一点。
4、天然支持 AI
agent.decide(state)
AI 直接读写状态。
本质:
AI = 状态决策器
五、进阶:事件流
State 架构更完整的写法是:
Event → Service → Store → UI
1、事件
Button("攻击")
.onClick(() => gameService.attack())
2、Service
attack() {
gameStore.update({
score: gameStore.state.score + 5
})
}
3、UI 自动更新
Text(`Score: ${this.state.score}`)
整个链路:
用户 → 状态 → UI
六、进阶:加入 AI Agent
Agent 决策
class EnemyAgent {
decide(state) {
if (state.player.x > 100) {
return { action: "attack" }
}
return { action: "idle" }
}
}
执行
const action = agent.decide(gameStore.state)
gameStore.update({
enemyAction: action
})
本质:
AI 也是“状态输入源”
七、进阶:动画与“伪帧循环”
有人会问:
没有 Game Loop,动画怎么办?
方案:局部驱动
setInterval(() => {
gameStore.update({
player: {
...gameStore.state.player,
x: gameStore.state.player.x + 1
}
})
}, 16)
注意:
不是驱动渲染,而是驱动状态
UI 依然自动更新。
八、常见错误
1、绕过 Store
this.state.player.x++
错误:状态不统一。
2、UI 写逻辑
onClick(() => this.score++)
应该走 Service。
3、过度使用 setInterval
会变回 Game Loop。
4、状态拆太散
导致不可控。
九、一句话理解这个架构
如果你只记住一句话:
游戏不是“不断渲染”,而是“不断变化的状态”。
总结
State 驱动鸿蒙游戏架构,可以总结为:
Store(唯一状态)
Service(逻辑)
UI(渲染)
Agent(AI)
核心链路:
Input → Service → Store → UI
↑
Agent
在 HarmonyOS 中,这种架构带来的不是“写法变化”,而是:
游戏从“帧驱动系统”
→
状态驱动系统
谁掌握了 State,谁就掌握了鸿蒙游戏的核心架构。
更多推荐




所有评论(0)