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.2 -在处理器子类中不再需要调用 super()
这将消除相当数量的样板文件。自述文件也已更新 有更多的使用示例。所有方法现在都应该至少有一个示例。最后, 轮子现在上传到pypi。这有助于包装系统只支持 车轮。解决问题38。
1.0.0 -esper现在默认在内部使用简单的lru缓存。缓存当前
从世界添加或删除实体或组件时刷新,组件查询 否则会更快。在未来的版本中,这可能会得到改进。此外 为了缓存,esper现在支持将kwarg传递给处理器。持续集成测试 正在为Python3.7完成。
0.9.9 -此版本的最大变化是ESPER已被压缩为单个
文件: esper.py 。这样就可以很容易地放入项目文件夹, 不需要在你的项目中添加一些不需要的文件夹 存在。如果你愿意的话,你仍然可以通过pip从pypi安装它,但是这很容易。 与您的项目一起发布(当然,许可证允许这样做)。
0.9.8 -此版本包含一个新计时器,可以启用该计时器来分析处理器执行情况 时间。只需在实例化时向world传递"timed=true"参数,然后 将提供world.process_times字典。包含总执行时间 以毫秒为单位,可以记录、打印或显示在屏幕上 是有用的。查看哪个处理器使用最多CPU的快速配置文件很有用 时间,没有完全剖析你的游戏。这个版本还包含一些整合 以及基准的清理。
0.9.7 -默认情况下,实体现在被惰性地删除。调用world.delete实体(实体id),
实体现在被放入一个队列中,以便在下次调用开始时删除 到world.process()。这意味着即使在迭代时也可以安全地删除实体。 在处理器的组件上。这应该允许更干净的处理器类,通过 消除了迭代后手动跟踪和删除"死"实体的需要。如果你 确实希望立即删除实体,只需传递新的可选 immediate=true 争论。即: self.world.delete_entity(entity,immediate=true)

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 。 进入预定方法。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Java中是否有数字的默认类型   java调用一个类的方法来使用另一个类的实例   java HtmlUnit不适用于javascript处理   java需要帮助才能连接MongoDB   java如何从Maven中的src/main/resources复制文件?   java保存Int值(共享首选项)   从另一个类调用方法时,java Autowired组件出现空指针异常   java Spring JPA:PropertyAccessException 1:。。。MethodInvocationException:。'driverClassName'。。。org/postgresql/Driver:不支持的专业。次要版本52.0   java使用增强的JDO模型类在Eclipse中运行Junit测试   java如何使用eclipse IDE为junit创建可运行的jar文件   java如何在安卓中检测应用程序的启动和退出   java在其他线程可以访问静态映射时从数据库更新静态映射   java@Entitty和@EntityScan不起作用。我正在使用SpringBoot和jpa存储库,发生了很多次   java如何与google日历集成?