2012-04-09 5 views
1

Ich versuche Spieler Kollisionen mit einem Sensor Körper zu erkennen. Stellen Sie sich ein Sammlerstück in einem Platformer vor ... Ich möchte ein Ereignis veranstalten, wenn der Spieler mit dem Sammlerstück kollidiert.Libdgx Box2D - Erkennen von Kollisionen

Wie Sie aus meinem Code entnehmen können, befestige ich einen dynamischen Körper an dem Sammelobjekt sowie einen Sensorkörper, an den ich ein Spielerkollisionsereignis anhängen möchte, wenn der Player mit dem Sensor kollidiert. Es scheint, dass es eine "ContactListener" -Schnittstelle gibt, aber die Implementierung der Methoden scheint nichts zu tun. Wie würde ich das machen?

Wenn es ein besserer Weg, eine der unten zu tun, würde jede Beratung geschätzt werden :)

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; 
    } 

} 

Antwort

0

Versuchen Sie diese Zeile im Code hinzufügen (at Münze Konstruktor):

bodyDef.userData = this;

Und Ihr Kontakt Listener, get userdata und Casting in GameObject, dann zum Beispiel Ereignis Kollision aufrufen.

Grüße

0

Sie haben Kollision Sensor Körper im Sein Kontakt oder Ende Kontakt von box2d collisionlisiter Methode

0

Zwei Dinge zu überprüfen, die falsch sein können:
1) OP nicht richtig die ContactListener gesetzt haben die box2d.World
2) werden die Kategorie und Maskenbits nicht korrekt nach der Instanziierung so eingestellt, dass es nicht die ContactListener

Lösung auslösen:
1) Setzen Sie das nach der Instanziierung der Physikwelt , die in dem Beispiel fehlt. Dadurch wird der ContactListener für Ihre box2d.World festgelegt, sodass etwas ausgelöst werden kann.

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) legen Sie die Kategorie und Maskenbits auf diese Weise, so dass Sie es testen können, wenn Werke (OP nicht die spezifischen Werte in seinem PhysicsLayers verwendet zeigten)

public CoinCollectible(Vector2 position, float angle){ 
    // ... 
    itemFixture.filter.categoryBits = 1; 
    itemFixture.filter.maskBits = 2; 
    sensorFixture.filter.categoryBits = 2; 
    sensorFixture.filter.maskBits = 1; 
} 
+0

Bitte erklären, was falsch ist mit dem OP-Code und warum dies das Problem löst * durch Bearbeiten Ihrer Antwort. * –