benmoran56 / esper

An ECS (Entity Component System) for Python
MIT License
537 stars 67 forks source link

enhance `get_component` #70

Closed zhengxyz123 closed 1 year ago

zhengxyz123 commented 2 years ago

Read the following code:

>>> import esper
>>> class Entity: pass
>>> class Animal(Entity): pass
>>> world = esper.World()
>>> world.create_entity(Entity())
1
>>> world.create_entity(Animal())
2
>>> world.get_component(Entity)
# a list has 1 item
>>> world.get_component(Animal)
# a list has 1 item

I want to use esper as the entities manager in a game. After I tried the above code, I think get_component should be:

>>> world.get_component(Entity)
# a list has 2 objects include an Entity and an Animal
>>> world.get_component(Animal)
# a list has 1 Animal object

which can return the inherited classes from given component.

I think the ECS may store not only the animal's position and its velocity but the whole animal, which is easy for designing the game.

benmoran56 commented 2 years ago

Sorry for not replying sooner. I didn't get notified of this issue ticket. You can do this with the world.add_compoent method. There is a type_alias argument. For example:

entity1 = world.create_entity()
world.add_component(entity1, Lion(), type_alias=Animal)

This means that you can't add components when creating an entity. You have to do it in two steps. A full example:

import esper

world = esper.World()

# Base class:
class Animal:    pass

class Lion(Animal):    pass

class Tiger(Animal):    pass

class Bear(Animal):    pass

entity1 = world.create_entity()
world.add_component(entity1, Lion(), type_alias=Animal)

entity2 = world.create_entity()
world.add_component(entity2, Tiger(), type_alias=Animal)

entity3 = world.create_entity()
world.add_component(entity3, Bear(), type_alias=Animal)

for ent, animal in world.get_component(Animal):
    print(ent, animal)
zhengxyz123 commented 2 years ago

Can I use one more type likes type_alias=(Animal, Lion)?

benmoran56 commented 2 years ago

No, that's not possible. It would be difficult to store in the DB, and difficult to query.

benmoran56 commented 1 year ago

I'm going to close this for now, but please feel free to reply if you want to discuss further.