【问题标题】:X velocity slowing down when applying Y Linear Impulse with Box2D使用 Box2D 应用 Y 线性脉冲时 X 速度减慢
【发布时间】:2015-11-05 15:47:13
【问题描述】:

我使用 libgdx 和 box2d 作为我的物理引擎。现在我只在一个平面上控制了一个非常简单的盒子:

一切似乎都运行良好。我用箭头键控制盒子。如果我按右箭头,框将向右加速。当我按向上箭头时,框会跳跃。 出乎意料的是,当盒子跳跃时,它的 x 速度变慢了。谁能告诉我这是为什么以及如何解决?

仅设置一些 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;
  }
}

【问题讨论】:

    标签: java libgdx box2d


    【解决方案1】:

    看看你的移动机制是如何工作的:

    1. 计算 forceX 和 forceY(根据按下的键)
    2. 应用 forceX 和 forceY

    当然你不能用它来跳跃以避免“飞行”,所以你使用 applyLinearImpulse() 来增加一次力(只需将它推到顶部)但棘手的部分是你取消您在 2. 中添加的 forceX - 请记住,在 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
    

    当然你可以考虑你自己的机制,但这是正确的方向

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 2014-09-20
      相关资源
      最近更新 更多