【问题标题】:AndEngine/Box2d/Java - collision detection between static and dynamic bodyAndEngine/Box2d/Java - 静态和动态体之间的碰撞检测
【发布时间】:2016-06-17 09:23:49
【问题描述】:

我正在检查.collidesWith 是否有两个不同身体类型的精灵发生碰撞。

下面的代码不会检测到与动态和静态主体的碰撞。我也想在碰撞后删除尸体。

当前代码:

ContactListener cl = new ContactListener() {

            @Override
            public void preSolve(Contact contact, Manifold oldManifold) {
                // TODO Auto-generated method stub

            }

            @Override
            public void postSolve(Contact contact, ContactImpulse impulse) {
                // TODO Auto-generated method stub

            }

            @Override
            public void endContact(Contact contact) {
                final Fixture x1 = contact.getFixtureA();
                final Fixture x2 = contact.getFixtureB();
            }

            @Override
            public void beginContact(Contact contact) {
                final Fixture x1 = contact.getFixtureA();
                final Fixture x2 = contact.getFixtureB();
                if (x1 != null && x1.getBody() != null
                        && x1.getBody().getUserData() != null) {
                    if (x2 != null && x2.getBody() != null
                            && x2.getBody().getUserData() != null) {
                        Log.d("TEST", "x1: "
                                + x1.getBody().getUserData().toString());
                        Log.d("TEST", "x2: "
                                + x2.getBody().getUserData().toString());

                        if (x2.getBody().getUserData().equals("Ball")
                                && x1.getBody().getUserData().equals("Dynamic")) {
                            destroy();
                        } else if (x2.getBody().getUserData().equals("Ball")
                                && x1.getBody().getUserData().equals("Static")) {
//                          ballSP.destroy();
                            // Toast.makeText(
                            // ResourcesManager.getInstance().activity,
                            // "touched static", Toast.LENGTH_LONG).show();
                        } else if (x2.getBody().getUserData().equals("Ball")
                                && x1.getBody().getUserData().equals("Figur")) {
//                          figSP.destroy();
                        }
                    }
                }
            }
        };

这是平台:

public void createPhysics() {
        if (bodyType != null) {
            FixtureDef FIXTURE = PhysicsFactory.createFixtureDef(0.0f, 0.0f,
                    1.0f);
            platformBody = PhysicsFactory.createBoxBody(physicsWorld, this,
                    bodyType, FIXTURE);
            physcConnector = new PhysicsConnector(this, platformBody, true,
                    true);
            physicsWorld.registerPhysicsConnector(physcConnector);
            physicsWorld.registerPhysicsConnector(new PhysicsConnector(this,
                    platformBody, true, true));
            this.setUserData(platformBody);
            platformBody.setLinearVelocity(physicsWorld.getGravity().x, 0);

            if (bodyType == BodyType.StaticBody) {
                platformBody.setUserData("Static");
                platformBody.setAwake(true);
            } else if (bodyType == BodyType.DynamicBody) {
                platformBody.setUserData("Dynamic");
//              platformBody.setAwake(true);
            }
        }

这是移动的球:

FixtureDef FIXTURE = PhysicsFactory.createFixtureDef(0.0f, 0, 1.0f);
        ballBody = PhysicsFactory.createBoxBody(physicsWorld, this,
                BodyType.DynamicBody, FIXTURE);
        physicsConnector = new PhysicsConnector(this, ballBody, true, true);
        physicsWorld.registerPhysicsConnector(physicsConnector);
        Vector2 shoot = new Vector2((6.78125f - 0.625f), (15.4375f - 0.625f));
        // shoot.nor().mul(4);

        scene.attachChild(this);

        // ResourcesManager.getInstance().camera.setChaseEntity(ballSP);

        ballBody.setLinearVelocity(shoot);
        ballBody.setAngularVelocity(0.5f);
        ballBody.setUserData("Ball");
        ballBody.setAwake(true);

如何检测静态和动态身体之间的碰撞,碰撞后应该移除身体和精灵?

【问题讨论】:

  • 使用 ContactListener 并在那里检查你的身体碰撞。
  • 我已经尝试过使用 ContactListener 但它没有检测到静态和动态主体之间的碰撞。
  • 你能展示你的代码吗?
  • 我已经编辑了我的问题
  • 现在我需要如何创建静态/动态主体的代码。我假设您没有看到任何日志消息,对吧?

标签: box2d andengine collision


【解决方案1】:

确定几件事:

1.启用小球的移动:

PhysicsHandler physicsHandler = new PhysicsHandler(ballBody);
ballBody.registerUpdateHandler(physicsHandler);

2。我的一个示例 ContactHandler

 @Override
public void beginContact(Contact contact) {
    final Fixture fixtureA = contact.getFixtureA();
    final Body bodyA = fixtureA.getBody();
    final Object userDataA = bodyA.getUserData();

    final Fixture fixtureB = contact.getFixtureB();
    final Body bodyB = fixtureB.getBody();
    final Object userDataB = bodyB.getUserData();

    GameBody givenGameBodyA = (GameBody) userDataA;
    GameBody givenGameBodyB = (GameBody) userDataB;

    LevelGameBodyType bodyTypeA = givenGameBodyA.getBodyType();
    LevelGameBodyType bodyTypeB = givenGameBodyB.getBodyType();

    if(areBodiesCollided(bodyTypeA, bodyTypeB, LevelGameBodyType.PLAYER, LevelGameBodyType.OBSTACLE)){
        Debug.v(TAG, "Player hit an obstacle!");

  }

private boolean areBodiesCollided(LevelGameBodyType givenGameBodyA, LevelGameBodyType givenGameBodyB, LevelGameBodyType wantedGameBodyA, LevelGameBodyType wantedGameBodyB) {
    return (givenGameBodyA.equals(wantedGameBodyA) || givenGameBodyA.equals(wantedGameBodyB))
            && (givenGameBodyB.equals(wantedGameBodyA) || givenGameBodyB.equals(wantedGameBodyB));

}

}

GameBody 是一个接口,LevelGameBodyType 是一个标识身体的 Enum。 因此,在您的 body 定义中,使用 GameBody 和 Identifier Enum 设置 UserData。

如果这没有帮助,请尝试在每个主体的 FixtureDef 中使用 isSensor = true。

FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.0f, 0.0f, true);

3.删除正文:

当你在当前线程上删除你的body时,你会遇到时间问题,所以不要这样做!

您确实应该为您的身体创建一个单独的 Java 类,例如MovingBall.java 等。

在这个类中你应该有一个这样的方法:

    @Override
public void removeFromPhysicsWorld() {
    isWaitingForDestruction = true;
    GameManager.get().getEngine().runOnUpdateThread(new Runnable() {
        @Override
        public void run() {
            body.setActive(false);
            physicsWorld.destroyBody(body);
        }
    });
}

在您的 ContactHandlerImpl 中,当身体发生碰撞时,请执行以下操作:

if(body.isWaitingForDestruction()){
            Debug.v(TAG, "Body waiting for destruction is " + body.getObjectId());
            return;
        }
        Debug.v(TAG, "Player collides with collectable! " + body.getObjectId());
        body.removeFromPhysicsWorld();

【讨论】:

    猜你喜欢
    • 2011-08-04
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多