2015-08-12 15 views
5

Używam libgdx i box2d jako mojego silnika fizyki. Teraz mam tylko bardzo prosta skrzynka kontrolowany na jednej płaskiej powierzchni:Zwolnienie prędkości X przy zastosowaniu Y Linear Impulse z Box2D

enter image description here

Wszystko wydaje się działać dobrze. Kontroluję pudełko za pomocą klawiszy strzałek. Jeśli naciśniesz prawą strzałkę, pole przyspieszy w prawo. Kiedy naciśniesz strzałkę w górę, pole przeskoczy. Coś, co było nieoczekiwane, polegało na tym, że kiedy skrzynia przeskakuje, prędkość x zwalnia. Czy ktoś może mi powiedzieć, dlaczego tak jest i jak to naprawić?

Object Player tylko niektóre konfiguracji 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); 
    } 
} 

ekranu gry:

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

Odpowiedz

0

zobaczyć, jak działa mechanizm poruszający:

  1. Oblicz forceX i forceY (ze względu na co są naciskane klawisze)
  2. Zastosuj forceX i forceY

oczywiście nie można go używać do skoku, aby uniknąć „pływa”, więc używasz applyLinearImpulse() aby dodać siły raz (tylko przesunąć do góry), ale trudne jest to, że są anulowanie forceX dodano w 2. - należy pamiętać, że w Box2D wykonuje wszystkie siły na world.step (...) Realizacja po wszystkich obliczeniach

Zamiast

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

zrobić coś

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

a następnie w renderowanie metoda

... 

    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 

Oczywiście można myśleć o własnym mechanizmem, ale to jest właściwy kierunek

Powiązane problemy