rednblackgames / HyperLap2D

A powerful, platform-independent, visual editor for complex 2D worlds and scenes.
https://hyperlap2d.rednblack.games/
GNU General Public License v3.0
376 stars 67 forks source link

Physics body is null #73

Closed taluks closed 3 years ago

taluks commented 3 years ago

Physics body is null.

  1. create physic body in editor
  2. load scene
  3. call PhysicsBodyComponent.body
  4. in 50% we can see error java.lang.NullPointerException

    • 0.0.8-snapshot
SceneConfiguration sc = new SceneConfiguration();
sc.setWorld(world);
sceneLoader = new SceneLoader(sc);
sceneLoader.loadScene("MainScene", viewport);
ComponentRetriever.addMapper(PlatformComponent.class); 

viewport.apply();
sceneLoader.getEngine().process();

ItemWrapper root = new ItemWrapper(sceneLoader.getRoot(), sceneLoader.getEngine());

ItemWrapper ball = root.getChild("ball");
ball.addScript(new CollisionScript(sceneLoader.getEngine()));
private World engine;
public CollisionScript(World engine) {
    this.engine = engine;
}   
@Override
public void init(int entity) {
    PhysicsBodyComponent pbComponent = ComponentRetriever.get(entity, PhysicsBodyComponent.class, engine);
/*93*/  pbComponent.body.setLinearVelocity(0, -20);
}
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.zench.game.script.CollisionScript.init(CollisionScript.java:93)
at games.rednblack.editor.renderer.utils.ItemWrapper.addScript(ItemWrapper.java:156)
at com.zench.game.screens.PlayScreen.show(PlayScreen.java:53)

♿♿♿ My solution: while(pbComponent.body==null) engine.process();

fgnm commented 3 years ago

Script has an act method which is called by the built in ScriptSystem that you can use to check if the body is null or not. Don't need to call process anywhere into script.

Btw, for this kind of question we have a Discord server where we can discuss, feel free to join :)

fgnm commented 3 years ago

Also, Scripts are automatically injected by artemis, so no need to pass world (engine) reference.. Use this as example:

public class PhysicsTestScript extends BasicScript implements PhysicsContact {
    //No needs to init these fields because scripts are injected using artemis 
    protected ComponentMapper<PhysicsBodyComponent> physicMapper;
    protected com.artemis.World engine;

    //This has to be initialized!
    private PhysicsBodyComponent physicsBodyComponent;

    @Override
    public void init (int item) {
        super.init(item);

        physicsBodyComponent = physicMapper.get(item);
    }

    @Override
    public void act (float delta) {
        //body can be used here, because act method is called after PhysicsSystem,
        //so all bodies should already be created
        Body body = physicsBodyComponent.body;
    }

    @Override
    public void beginContact (int contactEntity, Fixture contactFixture, Fixture ownFixture, Contact contact) {

    }

    @Override
    public void endContact (int contactEntity, Fixture contactFixture, Fixture ownFixture, Contact contact) {

    }

    @Override
    public void preSolve (int contactEntity, Fixture contactFixture, Fixture ownFixture, Contact contact) {

    }

    @Override
    public void postSolve (int contactEntity, Fixture contactFixture, Fixture ownFixture, Contact contact) {

    }

    @Override
    public void dispose () {

    }
}