2015-08-12 2 views
5

Я использую libgdx и box2d в качестве своего физического движка. Сейчас я просто очень простая коробка управляется на одной плоской поверхности:Х скорость замедления при применении Y Линейный импульс с Box2D

enter image description here

Все, кажется, работает хорошо. Я управляю коробкой с помощью клавиш со стрелками. Если я нажму на стрелку вправо, коробка ускорится вправо. Когда я нажимаю стрелку вверх, коробка будет прыгать. Что-то неожиданное, хотя было то, что когда коробка прыгает, скорость х замедляется. Может ли кто-нибудь сказать мне, почему это так и как это исправить?

Объект-плеер с только некоторые настройки 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); 
    } 
} 

Экран игры:

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

ответ

0

посмотреть, как работает ваш перемещающий механизм:

  1. Вычислить forceX а также forceY (из-за того, что клавиши нажимаются)
  2. Применить forceX и forceY

, конечно, вы не можете использовать его, чтобы прыгать, чтобы избежать «летающих», так что вы используете applyLinearImpulse() добавить силы один раз (только подтолкнуть его к вершине), но хитрая часть является то, что вы отменяете forceX вы добавили в 2. - помните, что в Box2D все силы выполняет на world.step (...) выполнения после всех расчетов

Вместо

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

сделать что-то вроде

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

, а затем в визуализации методы

... 

    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 

Конечно, вы можете думать о своем собственном механизме, но это правильное направление

Смежные вопросы