簡體   English   中英

使用Box2D應用Y線性脈沖時,X速度減慢

[英]X velocity slowing down when applying Y Linear Impulse with Box2D

我正在使用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;
  }
}

看看你的移動機制如何工作:

  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

當然,您可以考慮自己的機制,但這是正確的方向

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM