[英]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;
}
}
看看你的移動機制如何工作:
當然你不能用它來跳躍以避免“飛行”所以你使用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.