ECS框架初识

ECS框架

  • Entity(实体)
  • Component(组件)
  • System(系统)

ECS框架是一个为了迎合游戏开发,在进几年开始慢慢被推荐熟知的框架,最有代表性的作品就是《守望先锋》 ,其对传统的面向对象设计,组件化思维做了进一步的拆解,分成了Entity,Component,System3个部分,三者关系如图:
在这里插入图片描述

下面具体说一下这3个部分的功能和特性。

Entity

Entity就是我们的游戏世界的各个实体,如人物、枪支、建筑等等最直接的物体原型。无数个Entity构成勒我们整个游戏世界,同样,我们的游戏世界,也就是安装各个规则去运营各个Entity。在传统的面向对象中,一个实体一般是有各种属性,各种功能函数,各种继承、联合等关联的繁杂存在,在ECS框架中,Entity的作品相对简单,ECS会把各种数据拆分对应到各个Component中,Entity根据需求仅需挂载对应属性的Component,而不用关系具体的数据,且各种Component的逻辑处理拆分到对应各个System中,这样,Entity仅是一个包含多个Component的载体。

举个例子,游戏世界中一辆车,它是一个Entity,它能移动、碰撞、买卖,我们只需挂载对应moveComponent、crashComponent、tradeComponent组件即可,至于各个Component到底存了什么数据,怎么维护的,这都不是Entity需要考虑的,我们只要指定其能移动、碰撞、交易就好了,是不是很简单。

Component

做游戏开发的同学肯定对组件比较熟悉,Component是指具有某一个特定功能特性的组件,传统框架中,我们给一个对象挂载一个组件,通常是对对象附加对应的逻辑处理,从而来让对象具有对应的功能,而在ECS中,则把特定的功能特性划分得更彻底,更加强调解耦。对应这个思路,ECS中的Component可理解为专门存储对应特性的数据集合,而对应特性的逻辑,则放到对应的System中去处理。

仍然以上面的汽车的例子来讨论,汽车要移动,移动的这个特性对应游戏的实现其实是坐标的变化,那对应的数据就有position(x, y),这里我们以二维坐标为例,moveComponent则存放position数据,具体的position的坐标变化逻辑,则放到对应的moveSystem中去处理,我们给汽车挂载moveComponent,这样汽车就能移动勒。

这里另外要强调一点,在ECS的框架中,特定的Component是要整合到一起的,Component中通常会有一个所有component实例化对象的集合,这样处理的好处就是能达到功能解耦,也能做到利用内存cache,达到更好的性能。后文会再去强调这一点。

System

游戏世界中,肯定会有各种各样的规则,我们把各种规则,再细分成各个系统,划分依据是系统最好是功能专一,与其它系统不能耦合,ECS中把这些成为System,且与Component能对应,System主要处理对应Component的逻辑。

如上面汽车的例子,可能游戏世界,不止汽车会移动,玩家也能奔跑,其也能移动,总之,游戏世界中,所有挂载勒moveComponent的Entity都具有移动的功能,所有的moveComponent的移动逻辑,都归到moveSystem中去处理。

代码实例

有了以上的一些初步了解,那对比传统的面向对象,我们剖析一个案例,然后给出大致的代码框架,来更直接对比。
案例:一个简单的竞速比赛,参数的载具有汽车、摩托车,且每个选手之间能发生碰撞,并掉血,若血量为0,则直接出局。

传统OOB设计

class Racer {
  hp: number; // 血量
  crashDecHp: number; // 碰撞扣除血量
  maxSpeed: number; // 最大速度
  accSpeed: number; // 加速度
  posX: number; // 横坐标
  posY: number; // 纵坐标
  // 处理碰撞逻辑
  checkCrash(){ ...}
  // 处理血量逻辑
  updateHp() { ...}
    // 处理移动逻辑
  updatePos() { ...}
}

class GameManager {
  allRacer: Racer[];

  updateGameLogic() {
    allRacer.forEach((racer) => {
      racer.updatePos();
      racer.checkCrash();
      racer.updateHp();
    });
  }
}

ECS

// entity和component的映射关系,可以根据自己需求去设计,这里只给出最简单的设计,仅供参考
class Racer {
	id: number
}

class MoveComponent: {
  static allMoveCom: MoveComponent[]; // 所有移动组件集合
  // 在entity上挂载component
  static registerCom(entity: Racer) {
    let newCom = new MoveComponent();
    this.allMoveCom.push(newCom);
  }
  // 销毁整个Component
  static destory();

  target: Racer; // 挂载的Entity对象,可根据自己需求设计entity和component的映射关系
  posX: number; // 横坐标
  posY: number; // 纵坐标
  speed: number; // 当前速度

  // 注销组件
  cancelComponent();
}

class MoveSystem {
  static Instance(): MoveSystem;
  updatePos(dt) {
    MoveComponent.allMoveCom.forEach((com) => {
      com.posX += com.speed * dt;
      // ...
    });
  }
}

class GameManager {
  // 注册System
  registerSystem();
  // 注销System
  cancelSystem();

  updateGameLogic() {
    MoveSystem.Instance.updatePos();
    // HPSystem,CrashSystem 类比MoveSystem
  }
}

ECS的优势

  • 将数据更有效的组织,提高CPU cache利用率
    关于cache的利用率的好处,更多信息大家可以参考ECS 真的是「未来主流」的架构吗?的各位大牛的探讨。
  • 逻辑更彻底的解耦,便于并行、扩展、整合
    逻辑解耦是所以框架都希望的解决的。传统的框架也是力求将游戏能拆分更好更干净的模块。

总结

ECS的并不是一个突如其来的框架,其思想在传统的游戏开发中多少都会运用到,比如“输入指令”,“网络模块”,各种单例的Manager类等等,其思想很接近ECS,只不过他们更多的吧ECS整合到一个类中,即保存数据,又处理逻辑,能完成单一独立的逻辑。ECS的思想则是看到这种设计的好处,把其严格的扩展到项目的所有逻辑处理中,所有的逻辑都拆分成System,需要参与其中的Entity挂载对应Component,这样项目的逻辑就非常解耦,便于扩充,维护。

一个东西出现,很容易被其亮眼的地方所吸引,但同时我们也要多思考其是否真的那么完美,这里推荐大家阅读下《ECS 真的是「未来主流」的架构吗?》,不一定要为了ECS就强行套用,等自己发现项目的System逻辑臃肿,自己也分不清怎么去解耦时,给自己带来的反而是困扰。

ECS本人并没有实际的项目经验,对其的理解可能也是停留在很肤浅的表面,本文的论述仅供参考,欢迎探讨指正。

参考资料

ECS 真的是「未来主流」的架构吗?
浅谈《守望先锋》中的 ECS 构架
游戏开发中的ECS 架构概述

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript ECS框架是一种用于游戏开发的框架,它基于实体-组件-系统的设计模式。在这种框架中,游戏对象被表示为实体,每个实体由一组组件组成,而系统则负责处理这些实体和组件之间的交互。 在给出的引用中,可以看到一个简单的JavaScript ECS框架的实现。在这个框架中,主要的文件结构包括游戏逻辑入口文件(main.js)、角色系统(character.js)、碰撞系统(collision.js)、衰减系统(decay.js)、敌人系统(enemy.js)、渲染系统(render.js)、四叉树划线辅助系统(sketch.js)、时间系统(time.js)、用户输入系统(userInput)等。这些系统负责处理不同的游戏逻辑,例如角色的移动、碰撞检测、渲染等。 在加载框架时,首先通过异步加载main.js文件,并获取到canvas和主角图片等对象。然后,加载完毕后调用gameStart函数来启动ECS框架。gameStart函数接受canvas、dom和img作为参数,用于初始化ECS框架ECS框架的核心思想是将游戏对象分解为实体和组件,通过系统来处理它们之间的交互。实体是游戏对象的容器,组件是实体的属性或行为。系统则负责处理特定类型的组件,例如渲染系统负责处理渲染相关的组件。 通过使用ECS框架,开发者可以更好地组织和管理游戏逻辑,提高代码的可维护性和可扩展性。同时,ECS框架也能够提供更好的性能,因为它可以更有效地处理游戏对象之间的交互。 总结起来,JavaScript ECS框架是一种用于游戏开发的框架,基于实体-组件-系统的设计模式,通过将游戏对象分解为实体和组件,并通过系统来处理它们之间的交互,提供了更好的代码组织和管理方式,以及更好的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值