Adding child to Entity
Adding child to Entity
In certain circumstances, having a group of entities could be a plus. When it’s about animating some particles, having a “group” of particles would greatly simplify their management.
And in terms of architecture, adding the Group notion is complex, and introducing another level of hierarchy through a différent object may drive us to an unhandy situation; let’s try having some child!
New child attribute
In the existing Entity
class, we add a new child attribute with some helpers to add a child Entity
or to get all the child entities.:
public static class Entity {
//...
private Collection<Entity> child = new ArrayList<>();
//...
public Entity add(Entity c) {
child.add(c);
return this;
}
public Collection<Entity> getChild() {
return child;
}
//...
}
And we must also introduce an update delegation :
public void update(long d) {
child.stream().forEach(c -> update(d));
}
processing child Entities
As an Entity has a child, we must update the draw method to process those children!
public void update(long d) {
Collection<Entity> entities = sceneManager.getCurrent().getEntities();
entities.stream()
.filter(e -> !e.getPhysicType().equals(PhysicType.NONE))
.sorted(Comparator.comparingInt(Entity::getPriority))
.forEach(e -> {
//...
e.getChild().forEach(c -> applyPhysics(c, world, d));
e.update(d);
});
sceneManager.getCurrent().update(this, d);
}
and the draw process :
public void draw() {
// prepare a rendering pipeline
//...
// Draw things
Collection<Entity> entities = sceneManager.getCurrent().getEntities();
entities.stream()
.filter(Entity::isActive)
.sorted(Comparator.comparingInt(Entity::getPriority))
.forEach(e -> {
// <1>
draw(e, g);
// <2>
e.getChild().forEach(c -> draw(c, g));
});
sceneManager.getCurrent().draw(this, g);
//...
}
// <3>
private void draw(Entity e, Graphics2D g) {
switch (e.getClass().getSimpleName()) {
case "TextObject" -> {
drawTextObject((TextObject) e, g);
}
case "Entity" -> {
drawEntity(e, g);
}
case "GridObject" -> {
drawGridObject((GridObject) e, g);
}
}
}
- delegate the draw entity process to a separated method (<3>),
- parse all the children and draw them
There is also An impact on the Scene#input()
where all the child Entity
must be processed:
public void input() {
// <1>
sceneManager.getCurrent().input(this);
// <2> process all input behaviors
sceneManager.getCurrent().getEntities().stream()
.filter(KarmaPlatform.Entity::isActive)
.forEach(e -> {
processInput(e);
});
}
public void processInput(Entity e) {
// <3> apply entity's behaviors
if (!e.getBehaviors().isEmpty()) {
e.getBehaviors().forEach(b -> {
b.onInput(this, e);
});
}
// <4> apply child's behaviors.
e.getChild().forEach(c -> processInput(c));
}
- process the possble
Scene
specific input, - parse all the entities in the active scene and ask for processing Entity,
- Process all the
Behavior#inInput
for entities, - and apply t esame processing for all child entities.
Note for the Future
The child attribute will be useful as soon as we will implement some particles where each particle will share some common behaviors. A specificBehavior
will be set on the parentEntity
object having all the childEntity
acting as particles, and thisBehavior
will be applied on all of them.