为什么我的代码无法检测两个动态物体之间的碰撞?

时间:2014-11-13 04:09:19

标签: java android libgdx

这是我的代码:

public class Physics3 extends ApplicationAdapter {

        SpriteBatch batch;
        Sprite sprite, sprite2;
        Texture img;
        World world;
        Body body, body2;
        Body bodyEdgeScreen;

        Matrix4 debugMatrix;
        OrthographicCamera camera;

    //    final float PIXELS_TO_METERS = 100f;

        final short PHYSICS_ENTITY = 0x1;    // 0001
        final short WORLD_ENTITY = 0x1 << 1; // 0010 or 0x2 in hex

        @Override
        public void create() {
            batch = new SpriteBatch();
            img = new Texture("badlogic.jpg");

            // Create two identical sprites slightly offset from each other vertically
            sprite = new Sprite(img);
            sprite.setPosition(-sprite.getWidth()/2,-sprite.getHeight()/2 +200);
            sprite2 = new Sprite(img);
            sprite2.setPosition(-sprite.getWidth()/2 + 20,-sprite.getHeight()/2 + 800);

            world = new World(new Vector2(0, -100f),true);

            // Sprite1's Physics body
            BodyDef bodyDef = new BodyDef();
            bodyDef.type = BodyDef.BodyType.DynamicBody;
            bodyDef.position.set(sprite.getX() + sprite.getWidth()/2,
                    sprite.getY() + sprite.getHeight()/2);

            body = world.createBody(bodyDef);


            // Sprite2's physics body
            BodyDef bodyDef2 = new BodyDef();
            bodyDef2.type = BodyDef.BodyType.DynamicBody;
            bodyDef2.position.set(sprite2.getX() + sprite2.getWidth()/2,
                    sprite2.getY() + sprite2.getHeight()/2);

            body2 = world.createBody(bodyDef2);

            // Both bodies have identical shape
            PolygonShape shape = new PolygonShape();
            shape.setAsBox(sprite.getWidth()/2, sprite.getHeight()/2);

            // Sprite1
            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = shape;
            fixtureDef.density = 0.1f;
            fixtureDef.restitution = 0.5f;
            fixtureDef.filter.categoryBits = PHYSICS_ENTITY;
            fixtureDef.filter.maskBits = WORLD_ENTITY;

            // Sprite2
            FixtureDef fixtureDef2 = new FixtureDef();
            fixtureDef2.shape = shape;
            fixtureDef2.density = 0.1f;
            fixtureDef2.restitution = 0.5f;
            fixtureDef2.filter.categoryBits = PHYSICS_ENTITY;
            fixtureDef2.filter.maskBits = WORLD_ENTITY;

            body.createFixture(fixtureDef);
            body2.createFixture(fixtureDef2);

            shape.dispose();

            // Now the physics body of the bottom edge of the screen
            BodyDef bodyDef3 = new BodyDef();
            bodyDef3.type = BodyDef.BodyType.StaticBody;

            float w = Gdx.graphics.getWidth();
            float h = Gdx.graphics.getHeight();

            bodyDef3.position.set(0, 0);
            FixtureDef fixtureDef3 = new FixtureDef();
            fixtureDef3.filter.categoryBits = WORLD_ENTITY;
            fixtureDef3.filter.maskBits = PHYSICS_ENTITY;

            EdgeShape edgeShape = new EdgeShape();
            edgeShape.set(-w/2,-h/2,w/2,-h/2);
            fixtureDef3.shape = edgeShape;

            bodyEdgeScreen = world.createBody(bodyDef3);
            bodyEdgeScreen.createFixture(fixtureDef3);
            edgeShape.dispose();

            camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());

            createContactListener();
        }

        @Override
        public void render() {

            camera.update();
            // Step the physics simulation forward at a rate of 60hz
            world.step(1f/60f, 6, 2);

            sprite.setPosition((body.getPosition().x) - sprite.getWidth()/2 ,
                    (body.getPosition().y) -sprite.getHeight()/2 );
            sprite.setRotation((float)Math.toDegrees(body2.getAngle()));

            sprite2.setPosition((body2.getPosition().x) - sprite2.getWidth()/2 ,
                    (body2.getPosition().y) -sprite2.getHeight()/2 );
            sprite2.setRotation((float)Math.toDegrees(body.getAngle()));

            Gdx.gl.glClearColor(1, 1, 1, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

            batch.setProjectionMatrix(camera.combined);
            batch.begin();

            batch.draw(sprite, sprite.getX(), sprite.getY(),sprite.getOriginX(), sprite.getOriginY(),
                    sprite.getWidth(), sprite.getHeight(), sprite.getScaleX(), sprite.getScaleY(), sprite.getRotation());
            batch.draw(sprite2, sprite2.getX(), sprite2.getY(),sprite2.getOriginX(), sprite2.getOriginY(),
                    sprite2.getWidth(), sprite2.getHeight(), sprite2.getScaleX(), sprite2.getScaleY(), sprite2.getRotation());
            batch.end();
        }

        @Override
        public void dispose() {
            img.dispose();
            world.dispose();
        }

        private void createContactListener() {

            world.setContactListener(new ContactListener() {

                @Override
                public void beginContact(Contact contact) {
                    // TODO Auto-generated method stub
                    Body bodyA = contact.getFixtureA().getBody();
                    Body bodyB = contact.getFixtureB().getBody();
                    Gdx.app.log("beginContact", "between " + bodyA.toString() + " and " + bodyB.toString());
                }

                @Override
                public void endContact(Contact contact) {
                    // TODO Auto-generated method stub
                    Body bodyA = contact.getFixtureA().getBody();
                    Body bodyB = contact.getFixtureB().getBody();
                    Gdx.app.log("endContact", "between " + bodyA.toString() + " and " + bodyB.toString());
                }

                @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

                }

            });
        }

}

我有一个问题:为什么这段代码无法检测到两个动态物体之间的接触?它只能检测动态和静态物体之间的碰撞。

1 个答案:

答案 0 :(得分:1)

这是预期的结果,因为您正在过滤动态实体之间的碰撞:

 fixtureDef2.filter.categoryBits = PHYSICS_ENTITY;
 fixtureDef2.filter.maskBits = WORLD_ENTITY;

这表示fixtureDef2PHYSICS_ENTITYcategoryBits)并且应该与WORLD_ENTITYmaskBits)发生冲突。 如果您希望它与PHYSICS_ENTITY发生碰撞,则需要将maskbits设置为PHYSICS_ENTITY | WORLD_ENTITY
基本上碰撞过滤是这样完成的:

boolean collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0;

在您的实际案例中,这是:

0010 & 0001 != 0 && 0001 & 0010 != 0

false,因此没有碰撞。

Here您可以阅读有关碰撞过滤的更多信息。