What is best-practice for making Zay-ES en Bullet physics work nicely together? Or isn’t there one?
Currently I have a simple “game” which a car (PhysicsVehicle) and a track (RigidBody). I implemented a basic entity system based on the Space Invaders tutorial.
I integrated the physics system by creating a PhysicsAppState class that extends from BulletAppState. It handles all entities that have a Physics component, as follows:
ed = stateManager.getState(EntityDataState.class).getEntityData();
entities = ed.getEntities(Physics.class, Model.class);
controlTarget = ed.getEntities(ControlTarget.class, Physics.class);
There is also one entity that has a “ControlTarget” component, which determines which PhysicsControl is controlled by the player.
The override of the update method gets the players input from the entity system and applies it to the Physics control:
@Override
public void update(float tpf) {
if (controlTarget.applyChanges()) {
controlTarget.stream().findFirst().ifPresent(e -> {
VehicleControl c = (VehicleControl) controls.get(e.getId());
ControlTarget t = e.get(ControlTarget.class);
if (c != null && t != null) {
c.accelerate(t.getAcceleration());
c.brake(t.getBraking());
c.steer(t.getSteeringPosition());
}
});
}
super.update(tpf);
if (entities.applyChanges()) {
removeControls(entities.getRemovedEntities());
addControls(entities.getAddedEntities());
updateControls(entities.getChangedEntities());
}
}
Since the models are controlled by the physics system, I need to update my entities with new positions, so things like the chase cam can follow the player. I do this in the VisualAppState. There, I filter out all entities that do not have a fixed position (as updating them would be a waste):
ed = this.app.getStateManager().getState(EntityDataState.class).getEntityData();
allEntities = ed.getEntities(Position.class, Model.class);
movingEntities = ed.getEntities(
Filters.fieldEquals(Position.class, "isFixed", false),
Position.class,
Model.class);
And in the update override I update their positions:
@Override
public void update(float tpf) {
if (allEntities.applyChanges()) {
removeModels(allEntities.getRemovedEntities());
addModels(allEntities.getAddedEntities());
}
if (movingEntities.applyChanges()) {
for (Entity e : movingEntities) {
// update positions for spatials that are controlled by the physics system
Spatial o = models.get(e.getId());
e.set(new Position(o.getWorldTranslation().clone()));
}
}
}
Is this a sensible way of doing things? I read somewhere else that people are listening to a physics ticker instead. Is that a better approach?