Changing entities
Entities may be changed by altering the values / attributes of their components, adding new components, or removing existing components.
Accessing and changing individual components
The values of an entity’s component can be
accessed and changed via the get
and get_ptr
methods of world. Here, get
returns a reference,
which becomes a copy of the component if stored in a local variable,
and get_ptr
returns a pointer, which can write into
the original memory even if stored locally.
A reference to a component can be obtained as follows:
# Add an entity with a component
entity = world.add_entity(Position(0, 0))
# Get a reference to the position;
# storing this in a local variable makes it a copy
pos = world.get[Position](entity)
# This does not change the entity's state!
pos.x = 5
print(world.get[Position](entity).x == pos.x) # False
# Changing the reference in-place works, though.
world.get[Position](entity).x = 5
# Similarly, replacing the component completely
# works as well.
world.get[Position](entity) = Position(5, 0)
To access and change a component later in the current method, we use a pointer:
# Get a pointer to the Position component
pos_ptr = world.get_ptr[Position](entity)
# Now, changing the value via the local pointer variable works.
pos_ptr[].x = 10 # Use the `[]` operator to dereference the pointer
print(world.get[Position](entity).x == 10) # True
Of course, accessing a component only works if the entity has the component in question. Accessing a component that the entity does not have will result in an error.
# Add an entity without a velocity component
entity = world.add_entity(Position(0, 0))
with assert_raises():
# This will result in an error
_ = world.get[Velocity](entity)
We can check if an entity has a component using the
has
method.
# Check if the entity has a velocity component
if world.has[Velocity](entity):
print("Entity has a velocity component")
else:
print("Entity does not have a velocity component")
Setting multiple components at once
We can set the values of multiple components at once
using the set
method. This method takes an arbitrary number of
components and sets them all in one go.
# Add an entity with two components
entity = world.add_entity(Position(0, 0), Velocity(1, 1))
# Set multiple components at once
world.set(entity, Position(5, 5), Velocity(2, 2))
Adding and removing components
Components can be added and removed from entities using the
add
and remove
methods.
# Add an entity without components
entity = world.add_entity()
# Add components to the entity
world.add(entity, Position(0, 0), Velocity(1, 1))
# Remove a component from the entity
world.remove[Velocity](entity)
This works with arbitrary numbers of components, so we can add or remove any number of components at once.
If we want to remove some components and replace
them with other components directly, we can use the
replace
method in combination with the
by
method. The replace
method takes
Components to be removed as parameters, whereas the by
method
takes the new components to be added.
# Replace the position component with a velocity component
world.replace[Position]().by(Velocity(2, 2), entity=entity)
Similar to the add
and remove
methods, this works with arbitrary numbers of
components, so we can replace any number of components with
any other number of new components.
Tip
Replacing components in one go is significantly more efficient than removing and adding components separately.