2013-06-26 3 views
2

Я программирую игру в мяч, и я хочу, чтобы мяч не мог прыгать дважды, или прыгать, не касаясь пола.libGDX, Box2D, столкновение и запрет прыгать в воздух

Я использую методы beginContact() и endContact() от ContactListener для обнаружения, когда мяч прикасается пола. Я применил состояние (FLYING10 или LANDED), и я установил состояние шара в LANDED в методе beginContact() и сбросил его до FLYING в методе endContact(). Я проверяю это состояние, прежде чем применять силу прыжка.

Проблема заключается в том, что метод jump() вызывается в основном цикле рендеринга, а box2D иногда проводит две итерации цикла до вызова метода endContact(). Таким образом, метод jump() вызывается дважды до того, как box2D имитирует, что контакт с полом закончился.

Часть кода ContactListener (Это не ContactListener из libGDX, но методы beginContact() и endContact() вызов этих методов напрямую, минуя объект, который был сталкивающийся):

@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); 
    }  
} 

Часть из код шара 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(); 
    } 
} 

И выход консоли некоторые так:

Begin 
0 - Jump! 
1 - Jump! 
End 
Begin 
2 - Jump! 
End 

Я не знаю, почему это происходит, и если это лучший способ сделать это.

+0

Как насчет того, чтобы время ожидания составляло 0,2 секунды или что-то еще, прежде чем разрешить другой прыжок. – iforce2d

+2

Решение от ifroce2d: https://www.iforce2d.net/b2dtut/jumpability – Pavel

ответ

2
public void floorBeginContact(Contact contact){ 
state = State.LANDED; 
canApplyForce = true; 
} 

public void floorEndContact(Contact contact){ 
state = State.FLYING; 
} 

boolean canApplyForce = true; 

private void jump(){ 
if(state == State.LANDED){ 
    if(canApplyForce) 
    body.applyForceToCenter(0f, 30f); 
    canApplyForce = false; 
    System.out.println(i++ + " - Jump!"); 
} 
} 

public void act(float delta){ 
... 

if(Gdx.input.isKeyPressed(Keys.SPACE)){ 
    jump(); 
} 
    } 

Я думаю, что это должно решить вашу проблему.

+0

Это имеет недостаток, если попытка прыжка не отделяет игрока от земли (например, если над ними что-то тяжелое), то canApplyForce не будет сбрасываться в true. – iforce2d

+0

Thats именно то, что он хочет .... прыжок не может быть начат. Он хочет прыгать только один раз, когда мяч касается земли. Следующий прыжок может быть сделан только тогда, когда он покидает землю и снова прикасается к ней. –

+0

Справа. И если есть что-то тяжелое на вершине, он никогда не покинет землю и не коснется ее снова, поэтому canApplyForce не будет сброшен до истины, и после этого он больше не сможет прыгать. Вероятно, это не то, что он хочет. – iforce2d