I'm programming a ball game and I want the ball can't jump twice, or jump without having contact with the floor.
I'm using the methods beginContact()
and endContact()
from ContactListener
for detect when the ball is touching the floor. I implemented a state (FLYING
or LANDED
) and I set the ball state to LANDED
in the beginContact()
method, and reset it to FLYING
in the endContact()
method. I check this state before apply the jump force.
The problem is that the jump()
method is called in the main render loop and box2D sometimes spends two loop iterations before call endContact()
method. So the jump()
method is called twice before that box2D simulates that the contact with the floor has ended.
Part of the code of ContactListener
(This isn't the ContactListener
of libGDX, but the methods beginContact()
and endContact()
call these methods directly, passing the object which it was collide):
@Override
public void beginContact(Contact contact, Object objetB) {
if(objetB instanceof Floor){
System.out.println("Begin");
ball.floorBeginContact(contact);
}
}
@Override
public void endContact(Contact contact, Object objetB) {
if(objetB instanceof Floor){
System.out.println("End");
ball.floorEndContact(contact);
}
}
Part of the code of the ball Actor
:
public void floorBeginContact(Contact contact){
state = State.LANDED;
}
public void floorEndContact(Contact contact){
state = State.FLYING;
}
private void jump(){
if(state == State.LANDED){
body.applyForceToCenter(0f, 30f);
System.out.println(i++ + " - Jump!");
}
}
public void act(float delta){
...
if(Gdx.input.isKeyPressed(Keys.SPACE)){
jump();
}
}
And the console output is some like this:
Begin
0 - Jump!
1 - Jump!
End
Begin
2 - Jump!
End
I don't know why this happens and neither if this is the best way to do it.