更新如何在box2d碰撞后停止尸体

问题描述

如何在动态物体与动态物体碰撞时停止作用在之后的力?

enter image description here

我希望在发生碰撞时,一个物体能够移动body2,在碰撞之后,body2将停止。 我确实尝试了很多次以使用ContactListener,地面摩擦和播放器活动状态来解决此问题。不幸的是,我无法解决这个问题。有谁知道这应该如何工作?

我看不到附加代码的意义,但是我还是会这样做:

public class GameScreen implements Screen {
  ... 
  Player player;
  Player player2;
  
  @Override 
  public void show() {
    ... 
    world = new World(new Vector2(0,0f),true);
    
    player = new Player(world);
    player2 = new Player(world);
    
    moveDirection = new MoveDirection(player);
    shotDirection = new ShotDirection(player);
    ... 
  }
  
  @Override
  public void render(float delta) {
    world.step(1f/60f,6,2); 
    player.update();
    player2.update();
    ... 
  }
  ... 
}
public class Player {
  private final float PIXELS_TO_METERS = 100f;  
  private Sprite sprite;
  private World world;
  private Body body;
  ... 
  
  public Body getBody() 
  public void createBody() {
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.fixedRotation = true;
    bodyDef.position.set(
      sprite.getX() / PIXELS_TO_METERS,sprite.getY() / PIXELS_TO_METERS 
    );
    body = world.createBody(bodyDef);
    
    CircleShape shape = new CircleShape();
    shape.seTradius((long) (20) / PIXELS_TO_METERS);
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 0.1f; 
    body.createFixture(fixtureDef);
    shape.dispose();  
  }  
  public void update() {
    if(!isBodyCreated) {
      createBody();
      isBodyCreated = true;
    }
    //PrevIoUsly used:
    /*if(!isActive()) {
      body.setLinearVeLocity(0,0);
    }*/
    ... 
  }
  ... 
}
  

感谢阅读。

编辑:好的,我找到了一个解决方案,但该解决方案会出现延迟,请问该如何解决

enter image description here

public class GameScreen implements Screen {
  ...
  @Override
  public void render(float delta) {
    world.step(1f/60f,2); 
    player.update();
    player2.update();
    ...
  } 
  ... 
} 

public class MoveDirection extends Actor {
  ... 
  addListener(new InputListener() {
    ... 
    @Override
    public boolean touchDown(InputEvent event,float x,float y,int pointer,int button) {   
      ... 
      player.setActive(true);
      ... 
    } 
    ... 
    @Override
    public void touchUp(InputEvent event,int button) {
      ... 
      player.setActive(false); 
      player.getBody().setLinearVeLocity(0,0);
    } 
  ... 
} 

public class Player {
  private boolean active = false;
  ... 
  public void createBody() {
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.fixedRotation = true;
    bodyDef.position.set(
      (sprite.getX()) / PIXELS_TO_METERS,(sprite.getY()) / PIXELS_TO_METERS 
    );
    body = world.createBody(bodyDef);
    CircleShape shape = new CircleShape();
    shape.seTradius((long) (20) / PIXELS_TO_METERS);
    fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 0.1f; 
    //fixtureDef.restitution = 0; 
    body.createFixture(fixtureDef);
    shape.dispose();  
    body.setBullet(true);
    body.setUserData("player");
  }  
  public void setActive(boolean bool) {
    this.active = bool;
  }
  public boolean isActive() {
    return this.active;
  }  
  public boolean isContact() {
    boolean isContact = false;
    for(Contact contact : world.getContactList()) {
      if((contact.getFixtureA().getBody() == this.body || contact.getFixtureB().getBody() == this.body) && (contact.getFixtureA().getBody().getUserData() == "player" && contact.getFixtureB().getBody().getUserData() == "player")) {
        isContact = true;
        break;
      } 
    }
    return isContact; 
  } 
  public void update() {
    ... 
    if(!isContact() && !isActive()) {
      body.setLinearVeLocity(0,0);
    } 
  }
} 

解决方法

我对box2d没有任何经验,所以我无法给出详细的答案。但这也许就是实施EndContact和PostSolve方法的地方。

https://www.iforce2d.net/b2dtut/collision-anatomy