1

我正在尝试检测玩家与传感器主体的碰撞。想象一下平台游戏中的收藏品......我想在玩家与收藏品发生碰撞时运行一个事件。

正如您将从我的代码中看到的那样,我正在将一个动态主体附加到可收集对象以及一个传感器主体,我希望将一个玩家碰撞“事件”附加到玩家与传感器发生碰撞时。似乎有一个“ContactListener”接口,但实现这些方法似乎没有做任何事情。我该怎么做呢?

如果有更好的方法来执行以下任何操作,任何建议将不胜感激:)

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class CoinCollectible extends GameObject{

    public CoinCollectible(Vector2 position, float angle){
        bodyDef.type = BodyType.DynamicBody;
        bodyDef.position.x = position.x;
        bodyDef.position.y = position.y;
        bodyDef.angle = angle;

        PolygonShape poly = new PolygonShape();
        poly.setAsBox(1, 1);
        FixtureDef itemFixture = new FixtureDef();
        itemFixture.shape = poly;
        itemFixture.density = 1;
        itemFixture.filter.categoryBits = PhysicsLayers.LAYER_ITEM;
        itemFixture.filter.maskBits = PhysicsLayers.MASK_PLAYER;
        fixtureArray.add(itemFixture);

        massData.mass = 1f;

        // Attach a collision sensor
        FixtureDef sensorFixture = new FixtureDef();
        sensorFixture.shape = poly;
        sensorFixture.isSensor = true;
        sensorFixture.filter.maskBits = PhysicsLayers.LAYER_PLAYER;

        fixtureArray.add(sensorFixture);

        // Clean up
        poly.dispose();

    }
}

import java.util.ArrayList;
import java.util.List;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.MassData;
import com.badlogic.gdx.physics.box2d.World;

public class GameObject{

    public Body body = null;
    public BodyDef bodyDef = new BodyDef();
    public MassData massData = new MassData();

    protected List<FixtureDef> fixtureArray = new ArrayList<FixtureDef>();

    public GameObject(){}

    public Body addToWorld(World world){
        if(bodyDef == null)
            return null;

        body = world.createBody(bodyDef);

        while(fixtureArray.size() > 0){
            body.createFixture(fixtureArray.remove(0));
        }

        body.setMassData(massData);

        return body;
    }

}
4

3 回答 3

0

有两件事可能出错:
1)OP 在实例化 box2d.World 后没有正确设置 ContactListener
2)类别和掩码位设置不正确,因此不会触发 ContactListener

解决方案: 1)在实例化 示例中缺少
的物理世界之后立即放置。这将为您的 box2d.World 设置 ContactListener,以便触发某些内容。

physicsWorld = new World(new Vector2(0,-9),true);
physicsWorld.setContactListener(
    new ContactListener() {
        @Override
        public void beginContact(Contact contact) {
            Fixture fA = contact.getFixtureA();
            Fixture fB = contact.getFixtureB();
            Gdx.app.log("beginContact", "between " + fA.toString() + " and " + fB.toString());
        }

        @Override
        public void endContact(Contact contact) {
            Gdx.app.log("endContact", "between " );
        }

        @Override
        public void preSolve(Contact contact, Manifold oldManifold) {
            //you can leave this empty
        }

        @Override
        public void postSolve(Contact contact, ContactImpulse impulse) {
            //you can leave this empty
        }
    });

2)以这种方式设置类别和掩码位,以便您可以测试它是否有效(OP没有显示他的 PhysicsLayers 中使用的具体值)

public CoinCollectible(Vector2 position, float angle){
    // ...
    itemFixture.filter.categoryBits = 1;
    itemFixture.filter.maskBits =  2;
    sensorFixture.filter.categoryBits = 2; 
    sensorFixture.filter.maskBits = 1;
}
于 2014-09-14T14:42:47.503 回答
0

尝试在您的代码中添加这一行(在硬币构造函数中):

bodyDef.userData = this;

以及您的联系监听器,get userdata并转换为GameObject,然后,例如,调用事件冲突。

问候

于 2013-01-28T02:18:12.423 回答
0

您必须Sensor在 box2d collisionlisiter 方法的 Being contact 或 End Contact 中检查身体的碰撞

于 2013-12-06T12:11:46.840 回答