如何在box2d中在碰撞后停止物体

huangapple go评论63阅读模式
英文:

(updated) How to stop bodies after collision box2d

问题

以下是您要翻译的内容:

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

我期望在碰撞的瞬间,一个物体将能够移动物体2,而在碰撞之后,物体2将停止。我尝试了很多次用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;
    }
    //以前使用过:
    /*if(!isActive()) {
      body.setLinearVelocity(0, 0);
    }*/
    ... 
  }
  ... 
}
  

谢谢阅读。

**编辑:**好的,我找到了一个解决方案,但它有延迟,有什么办法可以修复它?

public class GameScreen implements Screen {
  ...
  @Override
  public void render(float delta) {
    world.step(1f/60f, 6, 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, float x, float y, int pointer, 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);
    } 
  }
} 
英文:

how to stopped the forces acting AFTER the collision of a dynamic body with a dynamic body?
如何在box2d中在碰撞后停止物体

I expect that at the moment of collision, one body will be able to move body2, and after the collision, body2 will stop.
I tried really many times to solve this with ContactListener, ground friction and player active states. Unfortunately, I have not been able to solve this. Does anyone know how this should work?

I don't see the point in attaching the code, but I'll do it anyway:

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);
}*/
... 
}
... 
}

Thanks for reading.

EDIT: Ok, I found a solution, but it works with a delay, what can I do to fix it?
如何在box2d中在碰撞后停止物体

public class GameScreen implements Screen {
...
@Override
public void render(float delta) {
world.step(1f/60f, 6, 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, float x, float y, int pointer, 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);
} 
}
} 

答案1

得分: 1

抱歉,由于您的要求,我只会返回翻译后的内容,不做其他回应。

我没有使用box2d的经验,所以无法给出详细的答案。但也许这就是应该实现EndContact和PostSolve方法的地方。

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

英文:

I haven't got any experience with box2d, so I can not give a detailed answer. But perhaps this is where the EndContact and PostSolve methods are ment to be implemented.

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

huangapple
  • 本文由 发表于 2020年10月13日 02:55:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/64323754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定