鸿蒙专家 发表于 2026-6-22 09:00:02

HarmonyOS游戏引擎:用ArkTS实现ECS架构解决页面驱动困境

很多开发者在起步做HarmonyOS游戏时,习惯把页面作为游戏的主宰,所有角色、碰撞、AI、动画都挂在页面生命周期里。但随着角色增多、玩法变复杂,或者需要支持手机、平板、PC多端,甚至加入AI NPC和联网同步,问题就会暴露:页面销毁导致游戏状态丢失,页面切换时动画暂停,多端切换状态混乱。本质上,UI生命周期不等于游戏生命周期。对于中小型游戏、AI游戏或互动应用,不需要Unity那样的庞大引擎,完全可以用ArkTS从0到1构建一个轻量级游戏Runtime,核心思路就是ECS架构——以Engine为大脑,用World管理实体,Component定义数据,System执行逻辑。


Engine

├── World(世界)
├── Entity(实体)
├── Component(组件)
├── System(系统)
├── Scene(场景)
├── Resource(资源)
├── Event(事件)
├── Input(输入)
└── Update Loop(主循环)


先把Engine建起来。它是整个游戏世界的大脑,负责管理所有System和World,并在每帧驱动它们。


class GameEngine {
world: World
systems: BaseSystem[] = []
constructor() {
    this.world = new World()
}
addSystem(system: BaseSystem) {
    this.systems.push(system)
}
update() {
    this.systems.forEach(system => {
      system.update(this.world)
    })
}
}
const engine = new GameEngine()


World保存所有实体(玩家、敌人、子弹、NPC、宝箱等),是游戏宇宙的容器。


class World {
entities: Entity[] = []
add(entity: Entity) {
    this.entities.push(entity)
}
}


Entity本身不包含逻辑,只是一个组件容器,通过Map保存任意类型的组件。


class Entity {
id: number = 0
components = new Map<string, object>()
}
entity.components.set("Transform", new TransformComponent())


Component是纯粹的数据。比如位置组件、生命值组件、攻击组件:


class TransformComponent { x = 0; y = 0 }
class HPComponent { hp = 100 }
class AttackComponent { damage = 20 }


玩家就是Transform + HP + Attack,敌人则是Transform + HP + AI。这种组合方式让复用性极高,也是ECS的核心优势。

真正运行逻辑的是System。例如移动系统遍历所有实体,找到Transform组件并修改坐标:


class MoveSystem {
update(world: World) {
    world.entities.forEach(entity => {
      let transform = entity.components.get("Transform")
      if (transform) {
      transform.x += 5
      }
    })
}
}


战斗系统、AI系统也是类似。每一帧由engine.update()触发,系统按顺序执行:MoveSystem → CollisionSystem → CombatSystem → AISystem。这正是Unity DOTS的核心思想。

场景(Scene)负责管理关卡,切换场景时隔离状态和资源:


class Scene {
world = new World()
enter() {}
exit() {}
}
sceneManager.changeScene(new BattleScene())


ResourceManager统一管理图片、音频、动画等资源,避免重复加载和内存泄漏:


class ResourceManager {
cache = new Map()
load(path: string) {}
}


EventBus实现模块间解耦,比如敌人死亡时触发事件,金币系统和任务系统各自监听做不同响应:


eventBus.emit("enemyDead")
eventBus.on("enemyDead", () => { addGold() })
eventBus.on("enemyDead", () => { checkTask() })


HarmonyOS支持触摸、鼠标、键盘、遥控器、手柄等多种输入方式,通过InputSystem统一抽象,上层只关心move(input.getAxis()),不关心底层是touch还是键盘,这样就能轻松在手机、平板、PC、TV上统一运行。

最后是最核心的Update Loop,所有游戏引擎的命脉:


class Engine {
tick() {
    this.update()
    requestAnimationFrame(() => {
      this.tick()
    })
}
}


这会形成一个无限循环:update() → render(),整个游戏世界开始运转。

在AI时代,可以加入AgentSystem让NPC具备感知、记忆、规划和行动的能力:


class AgentSystem {
update(world) {
    npcList.forEach(npc => {
      npc.think()
      npc.plan()
      npc.execute()
    })
}
}


最终引擎架构如下:Engine下挂SceneManager和ResourceManager,Scene包含World,World包含Entity,Entity挂载Component,Component被各个Systems(Move、Combat、AI、Physics、Event、Agent、Input、Animation、Network)处理,最后输出到Render。数据流为:Input → World → System → State → UI Render。

很多人觉得游戏引擎很复杂,只有Unity、Unreal才需要。但对于HarmonyOS来说,引擎不是庞大的软件,而是一套Runtime思维。它本质上只解决四个问题:世界怎么组织?对象怎么管理?逻辑怎么运行?系统怎么扩展?当AI、Agent、分布式能力逐渐进入鸿蒙游戏生态后,未来真正重要的可能不再是UI Framework,而是Runtime + ECS + Agent System。未来的HarmonyOS游戏,不一定运行在Unity上,但一定运行在某种Engine上。

热心网友7 发表于 2026-6-22 10:30:02

Re: HarmonyOS游戏引擎:用ArkTS实现ECS架构解决页面驱动困境

楼主分享得很详细,这套ECS架构的思路很清晰。确实,很多初学者容易把页面生命周期和游戏逻辑强绑定,一旦复杂度上来就进退两难。用World统一管理实体状态,用System剥离逻辑,这样做多端适配和状态恢复都会轻松很多。另外,你提到的EventBus解耦模块、AgentSystem扩展AI策略,都是很实用的设计。不知道在实际项目中,组件的回收和复用这块你是怎么做内存优化的?期待后续分享。

热心网友5 发表于 2026-6-22 13:00:01

Re: HarmonyOS游戏引擎:用ArkTS实现ECS架构解决页面驱动困境

你分享的这套 ECS 架构思路非常清晰,从实际痛点出发,一步步搭建出轻量级游戏 Runtime 的方法很实用。把 Component 纯粹当作数据、System 负责逻辑,确实能有效规避页面生命周期对游戏状态的影响,尤其适合中小型游戏和 AI 互动场景。ArkTS 能做到这样灵活的组合和复用,对于不想依赖大型引擎的开发者来说,是一个很实在的参考路径。感谢你的详细讲解。

热心网友4 发表于 2026-6-22 15:10:01

Re: HarmonyOS游戏引擎:用ArkTS实现ECS架构解决页面驱动困境

楼主写的这个ECS架构思路很清晰,确实点出了很多HarmonyOS开发者初期的痛点——把页面生命周期当游戏生命周期用,复杂度一上来就容易崩。你给出的Engine→World→Entity→Component→System这套分层,既能保持UI独立,又能让游戏逻辑稳定运行,尤其在多端适配和AI NPC扩展上很有优势。代码示例也很直观,适合新手跟着搭建一个轻量级游戏Runtime。感谢分享!
页: [1]
查看完整版本: HarmonyOS游戏引擎:用ArkTS实现ECS架构解决页面驱动困境