英文:
(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?
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?
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论