esper是一个针对python的轻量级实体系统,重点关注性能。
esper的Python项目详细描述
esper
esper是python的轻量级实体系统,注重性能。
ESPER是麻省理工学院授权的实体系统,或实体组件系统(ECS)。 该设计基于亚当·马丁在其博客中概述的实体系统概念。 http://t-machine.org/ 和其他。努力使它保持轻量化和高性能 尽可能。
在这篇维基百科文章中,有一篇相当准确的描述实体系统的文章: https://en.wikipedia.org/wiki/entity_component_system
灵感来自Sean Fisk的 ecs https://github.com/seanfisk/ecs , 以及marcus von appen的 ebs https://bitbucket.org/marcusva/python utils
新功能
< dl >1)兼容性
esper只是一个python 3库。具体来说,所有当前支持的python 3版本。 它还支持pypy3。由于是用纯python编写的,所以它应该在任何符合 翻译。对cpython和pypy3都进行了持续集成(自动测试)。
2)安装
无需安装。esper是一个没有依赖关系的小型库。简单复制 将esper.py 导入项目文件夹的顶层,然后导入esper
如果您愿意,也可以在pypi上使用esper,以便通过pip轻松安装。
3)项目结构
- 世界
在esper中,世界是交互作用的主要点。创建世界对象后,将使用 创建实体并将组件分配给它们的对象。一个世界也被分配给 您的处理器实例,并通过每帧一次调用来平稳地运行所有内容。 当然,实体、组件和处理器可以在 您的应用程序正在运行。
- 实体
实体是简单的整数id(1、2、3、4等)。 实体是"创建"的,但通常不直接使用。相反,他们是 简单地用作内部组件数据库中的id,以跟踪组件的集合。 创建实体是用world.create_entity()方法完成的。
- 部件
组件被定义为简单的python类。与纯粹的实体系统保持一致 设计理念,它们不应该包含任何逻辑。它们可能已经初始化 代码,但没有任何处理逻辑。一个简单的组件可能如下所示:
class Position: def __init__(self, x=0.0, y=0.0): self.x = x self.y = y
- 处理器
处理器,也称为"系统",是定义和执行所有处理逻辑的地方。 所有处理器都必须继承自 esper.processor 类,并具有名为 process 的方法。 除此之外,没有任何限制。所有处理器都可以访问World实例, 这就是查询要操作的组件的方式。一个简单的处理器可能看起来像:
class MovementProcessor(esper.Processor): def process(self): for ent, (vel, pos) in self.world.get_components(Velocity, Position): pos.x += vel.x pos.y += vel.y
在上面的代码中,您可以看到 world.get_components() 方法的标准用法。这个 方法允许对包含指定组件类型的所有实体进行有效的迭代。 此方法可用于同时查询两个或多个组件。注意元组解包 对于返回组件对是必需的: (vel,pos) 。除了组件,您还可以 获取对当前速度/位置对的实体id(ent对象)的引用 组件。这个实体id在各种情况下都很有用。例如,如果您的处理器 需要删除某些实体,可以调用 此实体ID。另一个常见用法是,如果您希望添加或删除此实体上的组件 因为满足了某些条件。
4)基本用法
导入esper后的第一步是创建一个world实例。你可以拥有一个单一的世界 为整个游戏设置实例,或者为每个游戏场景设置单独的实例。 任何对你的设计有意义的东西。创建这样的世界实例:
world = esper.World()
创建一些处理器实例,并将它们分配给世界。您可以指定 可选的处理优先级(先处理较高的数字)。所有处理器都是 默认情况下优先级"0":
movement_processor = MovementProcessor() collision_processor = CollisionProcessor() rendering_processor = RenderingProcessor() world.add_processor(movement_processor, priority=2) world.add_processor(collision_processor, priority=3) world.add_processor(rendering_processor) # or just add them in one line: world.add_processor(SomeProcessor())
创建一个实体,并为其分配一些组件实例:
player = world.create_entity() world.add_component(player, Velocity(x=0.9, y=1.2)) world.add_component(player, Position(x=5, y=5))
或者,组件实例可以在创建时直接分配给实体:
player = world.create_entity(Velocity(x=0.9, y=1.2), Position(x=5, y=5))
执行所有处理器只需调用world.process()一次。这将调用 在所有分配的处理器上按优先级排序的处理方法。这通常被称为 游戏每帧更新一次。
world.process()
注意:您可以传递 world.process() 所需的任何参数,但还必须确保接收 它们在处理器的 process() 方法中正确。例如,如果传递delta时间 参数为 world.process(dt) ,处理器的 process() 方法都应将其接收为: def过程(自,dt): 这适用于自动传递delta time值的库,如 pyglet 。 进入预定方法。