鸿蒙游戏的“帧”到底是什么?


子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案,

在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向: 前端 / 跨端 / 小程序 / 移动端工程化 内容平台: 掘金、知乎、CSDN、简书 创作特点: 实战导向、源码拆解、少空谈多落地 **文章状态:**长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在"API 怎么用",而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨

👋 如果你正在做前端,或准备长期走前端这条路

📚 关注我,第一时间获取前端行业趋势与实践总结

🎁 可领取 11 类前端进阶学习资源 (工程化 / 框架 / 跨端 / 面试 / 架构)

💡 一起把技术学"明白",也用"到位"

持续写作,持续进阶。

愿我们都能在代码和生活里,走得更稳一点 🌱

文章目录

引言

一提到"游戏帧(Frame)",很多人的第一反应是:

复制代码
60 FPS
每 16ms 执行一次
update → render

然后你很自然会在鸿蒙游戏里写出这样的代码:

ts 复制代码
setInterval(() => {
  engine.update(store)
}, 16)

你会觉得:

复制代码
OK,我的游戏已经有"帧"了

但当你继续开发,很快会遇到一些奇怪的问题:

复制代码
动画不流畅
状态更新不同步
多设备表现不一致
UI 有时候不刷新

这时候,一个关键问题浮现出来:

在鸿蒙(尤其是 ArkUI)里,"帧"到底是什么?

一、传统游戏里的"帧"

在传统引擎(比如 Unity)中:

一帧通常是:

复制代码
输入 → update → render → 输出

核心特点:

复制代码
开发者控制渲染
开发者控制循环
帧 = 渲染 + 逻辑

所以:

帧是一个"主动循环"

二、鸿蒙里的一个关键变化

在鸿蒙 + ArkUI 中:

复制代码
UI 是声明式的
渲染由系统驱动

你不会写:

ts 复制代码
render()

而是:

ts 复制代码
Text(store.hp.toString())

store.hp 改变时:

复制代码
UI 自动更新

这意味着一个本质变化:

正确 你不再控制"渲染帧"

错误 系统在控制"渲染节奏"

三、那"帧"还存在吗?

存在,但它已经变了。在鸿蒙中:

帧 ≠ 渲染循环

而是:

帧 = 一次"状态变更 → UI 刷新"的完整过程

也就是说:

复制代码
System 改变 Store
        ↓
ArkUI 感知变化
        ↓
触发 UI 更新
        ↓
完成一次"帧"

四、重新定义"帧"

你可以这样理解:

复制代码
传统游戏:
帧 = 主动执行一次循环

鸿蒙游戏:
帧 = 一次状态驱动的渲染结果

换句话说:

帧不再是"时间片",而是"状态快照"

五、为什么 setInterval 会出问题?

我们再看这段代码:

ts 复制代码
setInterval(() => {
  engine.update(store)
}, 16)

问题在于:

复制代码
你在强行制造"时间帧"
但 UI 并不按这个节奏刷新

结果可能是:

复制代码
逻辑 60fps
UI 不是 60fps
甚至被合并 / 丢帧

因为:

ArkUI 会自己做调度和合并更新

六、正确理解:逻辑帧 vs 渲染帧

在鸿蒙中,你需要区分两个东西:

1、逻辑帧

ts 复制代码
engine.update(store)

作用:

复制代码
推进游戏状态
执行 System

2、渲染帧

由 ArkUI 控制:

复制代码
检测状态变化
合并更新
刷新 UI

关键点:

这两者是解耦的

七、一个更合理的写法

你可以这样写:

ts 复制代码
class GameLoop {

  start(store) {
    const loop = () => {
      engine.update(store)
      requestAnimationFrame(loop)
    }
    loop()
  }

}

这里的关键不是 API,而是理念:

用"节奏提示",而不是"强控时间"

八、更进阶:无帧驱动

当你进一步理解后,你甚至可以不写"帧循环":

ts 复制代码
onUserInput(() => {
  battleSystem.attack(store)
})

onAIUpdate(() => {
  aiSystem.decide(store)
})

也就是说:

用"事件"驱动状态,而不是"帧"驱动

这种模式下:

复制代码
没有固定帧
只有状态变化

九、那游戏动画怎么办?

这是很多人最困惑的点:

没有帧,动画怎么做?

答案是:交给系统

在 ArkUI 中:

ts 复制代码
.animateTo({
  duration: 300
}, () => {
  this.x = 100
})

系统会负责:

复制代码
插值
补帧
平滑

你不需要手动控制:

复制代码
每一帧的位置

十、一个关键认知升级

初学者理解:

复制代码
帧 = 16ms 循环

进阶之后你会理解:

帧 = 状态变化的可视化结果

最终你会达到:

复制代码
不关心帧率
只关心状态

十一、这带来的架构变化

你会从:

复制代码
Frame Loop 驱动

变成:

复制代码
System 驱动

系统运行变成:

复制代码
输入(操作 / AI)
      ↓
System 更新状态
      ↓
ArkUI 自动渲染

十二、开发者常见误区

误区 1:强行 60fps

ts 复制代码
setInterval(..., 16)

结果:

复制代码
性能浪费
不同步
不稳定

误区 2:自己做动画

ts 复制代码
x += 1 // 每帧移动

问题:

复制代码
卡顿
复杂
不可控

误区 3:把帧当核心

结果:

复制代码
忽略状态
忽略 System
架构混乱

十三、一个终极理解

当你真正理解鸿蒙游戏之后,你会发现:

你写的系统,本质是:

一个"状态流动系统"

而不是:

复制代码
一个"帧循环系统"

总结

在鸿蒙游戏中:

复制代码
帧 ≠ 固定时间循环
帧 = 状态变化后的 UI 呈现

最终结构是:

复制代码
System(驱动状态)
        ↓
Store(状态变化)
        ↓
ArkUI(自动渲染)

如果用一句话总结:

鸿蒙游戏没有传统意义上的"帧循环",只有"状态驱动的帧结果"。

相关推荐
IntMainJhy1 小时前
【flutter for open harmony】第三方库 Flutter运动计时器的鸿蒙化适配与实战指南
flutter·华为·信息可视化·数据库开发·harmonyos
Hello__77771 小时前
开源鸿蒙 Flutter 实战|徽章组件全流程实现
flutter·开源·harmonyos
IntMainJhy1 小时前
【flutter for open harmony】 第三方库 Flutter饮食记录的鸿蒙化适配与实战指南
flutter·华为·信息可视化·数据库开发·harmonyos
Lanren的编程日记1 小时前
Flutter 鸿蒙应用数据统计分析功能实战:数据统计+数据可视化+报表生成,打造全链路数据分析能力
flutter·华为·信息可视化·harmonyos
Hello__77774 小时前
开源鸿蒙 Flutter 实战|自定义开关组件全流程实现
flutter·开源·harmonyos
maaath14 小时前
【maaath】Flutter for OpenHarmony 跨平台工程集成密码加密能力
flutter·华为·harmonyos
liulian091615 小时前
Flutter for OpenHarmony 混合开发实践:用户反馈功能的实现与适配
flutter·华为·学习方法·harmonyos
Hello__777716 小时前
开源鸿蒙 Flutter 实战|文章分类标签功能全流程实现
flutter·开源·harmonyos
penngo16 小时前
# 使用Claude Code开发植物大战僵尸游戏(pygame,附源码)
python·游戏·pygame