2015-08-12 11 views
5

Uso libgdx e box2d come motore fisico. In questo momento ho solo una semplice scatola controllato su una singola superficie piana:Velocity X che rallenta quando si applica Y Linear Impulse con Box2D

enter image description here

Tutto sembra funzionare bene. Controllo la scatola con i tasti freccia. Se premo la freccia destra, la casella accelera a destra. Quando premo la freccia su, la scatola salterà. Tuttavia, qualcosa di inaspettato era che quando la scatola salta, la velocità x rallenta. Qualcuno può dirmi perché è e come risolverlo?

oggetto Player con solo alcune operazioni di configurazione Box2d:

public class Player extends Entity { 
    private static BodyDef createBodyDef() { 
    BodyDef bodyDef = new BodyDef(); 
    bodyDef.type = BodyDef.BodyType.DynamicBody; 
    bodyDef.fixedRotation = true; 
    bodyDef.position.set(100, 200); 
    return bodyDef; 
    } 

    public Player(World world) { 
    super(world, createBodyDef(), Textures.rectangle(Units.m2P(0.7f), Units.m2P(2f), Color.RED)); 
    FixtureDef fixtureDef = new FixtureDef(); 
    PolygonShape shape = new PolygonShape(); 
    shape.setAsBox(50, 50, new Vector2(50, 50), 0f); 
    fixtureDef.shape = shape; 
    fixtureDef.friction = 0.1f; 
    getBody().createFixture(fixtureDef); 
    MassData massData = new MassData(); 
    massData.mass = 90f; 
    getBody().setMassData(massData); 
    } 
} 

La schermata di gioco:

public class GameScreen extends BaseScreen implements InputProcessor { 
    private final World world = new World(new Vector2(0, -200), false); 
    private final GameView view = new GameView(); 
    private final List<Entity> entities = new ArrayList<Entity>(); 
    private final Player player = new Player(world); 
    private final List<Integer> pressedKeys = new ArrayList<Integer>(); 

    public GameScreen() { 
    entities.add(player); 
    view.setFollowEntity(player); 
    MapBodyBuilder.buildShapes(view.getTiledMap(), 1, world); 
    } 

    @Override public void show() { 
    super.show(); 
    Gdx.input.setInputProcessor(this); 
    } 

    @Override public void render(float delta) { 
    super.render(delta); 

    float forceX = 0f; 
    float forceY = 0f; 
    float force = 15000; 
    if (pressedKeys.contains(Input.Keys.LEFT)) { 
     forceX -= force; 
    } 
    if (pressedKeys.contains(Input.Keys.RIGHT)) { 
     forceX += force; 
    } 
    if (pressedKeys.contains(Input.Keys.DOWN)) { 
     forceY -= force; 
    } 

    player.getBody().applyForceToCenter(forceX, forceY, false); 

    world.step(delta, 5, 5); 
    view.render(entities); 
    } 

    @Override public void resize(int width, int height) { 
    super.resize(width, height); 
    } 

    @Override public void hide() { 
    super.hide(); 
    Gdx.input.setInputProcessor(null); 
    } 

    @Override public void dispose() { 
    super.dispose(); 
    world.dispose(); 
    for (Entity entity : entities) { 
     entity.dispose(); 
    } 
    } 

    @Override public boolean keyDown(int keycode) { 
    if (keycode == Input.Keys.UP) { 
     Body body = player.getBody(); 
     body.applyLinearImpulse(new Vector2(0, 30000), body.getWorldCenter(), true); 
    } 

    pressedKeys.add(keycode); 
    return false; 
    } 

    @Override public boolean keyUp(int keycode) { 
    pressedKeys.remove((Integer) keycode); 
    return false; 
    } 

    @Override public boolean keyTyped(char character) { 
    return false; 
    } 

    @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { 
    return false; 
    } 

    @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { 
    return false; 
    } 

    @Override public boolean touchDragged(int screenX, int screenY, int pointer) { 
    return false; 
    } 

    @Override public boolean mouseMoved(int screenX, int screenY) { 
    return false; 
    } 

    @Override public boolean scrolled(int amount) { 
    return false; 
    } 

    public Player getPlayer() { 
    return player; 
    } 
} 

risposta

0

vedere come funziona il meccanismo di movimento:

  1. Calcolare forceX e Forcey (a causa di ciò che si premono i tasti)
  2. Applicare forceX e Forcey

, naturalmente, non è possibile utilizzarlo per saltare per evitare di "volante" in modo che si sta utilizzando applyLinearImpulse() per aggiungere forza una volta (solo spingerlo verso l'alto), ma la parte difficile è che si sta annullando forceX aggiunto nel 2. - ricordare che in tutte le forze Box2D esegue sul world.step (...) l'esecuzione dopo tutti i calcoli

anziché

if (keycode == Input.Keys.UP) 
    { 
     Body body = player.getBody(); 
     body.applyLinearImpulse(new Vector2(0, 30000), body.getWorldCenter(), true); 
    } 

fare qualcosa di simile

if (keycode == Input.Keys.UP) 
    { 
     jumpForce = 30000; //jumpForce is variable of GameScreen class 
    } 

e poi nel rendere metodo

... 

    if (pressedKeys.contains(Input.Keys.DOWN)) 
    { 
     forceY -= force; 
    } 

    forceY += jumpForce; //here you add the jump force 

    player.getBody().applyForceToCenter(forceX, forceY, false); 

    jumpForce = 0; //but only once - in next iteration od render it will be avoided till UP key will be pressed again 

Naturalmente si può pensare il proprio meccanismo, ma questa è la direzione giusta

Problemi correlati