ECS 简介
可参考的官方例子:
ecs_guide
.
还可以参考完整的游戏实例:
alien_cake_addict
,
breakout
.
ECS 作为数据结构
Bevy 使用 Bevy ECS(Entity-Component System)为你存储和管理所有数据。
从概念上讲,你可以把它与数据库或电子表格中的表格进行类比。你的不同数据类型(组件)就像表格的"列","行"(实体)包含多个组件的值或实例。
例如,你可以为你的游戏创建一个 Health
组件。然后,你可以有许多实体代表你游戏中的不同事物,如玩家、NPC 或怪物,所有这些事物都可以有一个 Health
值(以及其他相关组件)。
这使得编写游戏逻辑(Systems)变得很容易,它可以对任何具有必要组件的实体进行操控(例如健康/伤害系统可以操控任何具有 Health
的事物),不管那是玩家、NPC 还是怪物(或其他什么)。这使得你的游戏逻辑非常灵活和可重复使用。
一个给定的实体所具有的组件的集合或组合,被称为实体的原型。
请注意,实体并不局限于"游戏世界中的对象"。ECS 是一个通用的数据结构。你可以创建实体和组件来存储任何数据。
性能
Bevy 有一个智能的调度算法,可以尽可能地并行运行你的系统。当你的函数不需要对相同的数据进行冲突的访问时,它就会自动这样做。你的游戏将可以"自由"地扩展到在多个 CPU 核心上运行,也就是说,不需要你额外的开发努力。
为了尽可能地提高并行化运行,你可以使你的数据和代码更加细化。将你的数据分割成更小的类型和结构
。将你的逻辑分成多个小的系统或函数。让每个系统只访问与它相关的数据。访问冲突越少,游戏的运行速度就越快。
Bevy 性能的一般经验法则是:越细化越好。
给来自面向对象语言程序员的提示
你可能已经习惯了用"对象类"来思考。例如,你可能会想定义一个大的单体结构 Player,包含玩家的所有字段和属性。
在 Bevy 中,这被认为是不好的做法,因为这样做会使你的数据更难处理,并限制性能。
相反,当不同的数据片断可以被独立访问时,你应该让数据变得更细化。
例如,将游戏中的玩家表现为一个实体,由独立的组件类型(独立的 struct
)组成,如健康、XP 或任何与你的游戏有关的东西。你也可以将标准的 Bevy 组件如 Transform
(Transform 解释)附加到它上面。
这将使你更容易开发你的系统(游戏逻辑和行为),以及使你的游戏运行性能更好。
当然,像 Transform
这样的东西,或者一组坐标,不进一步细化,而作为一个单一的结构同样是有意义的,因为它的字段不可能独立发挥作用。