2012-04-09 2 views
1

Я пытаюсь обнаружить столкновение игрока с корпусом датчика. Представьте себе коллекционер в платформер ... Я хочу запустить событие, когда игрок сталкивается с коллекционируемым.Libdgx Box2D - Обнаружение столкновений

Как вы увидите из моего кода, я прикрепляю динамическое тело к коллекционируемому объекту, а также тело датчика, которое я надеюсь прикрепить к событию столкновения игрока, когда игрок сталкивается с датчиком. Кажется, есть интерфейс «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; 
    } 

} 

ответ

0

Попробуйте добавить эту строку в коде (в конструкторе монеты):

bodyDef.userData = this;

И ваш контакт-слушатель, get userdata и литье в GameObject, то, например, вызовите событие столкновения.

Приветствия

0

Вы должны проверить столкновение Sensor тела в бытии контакте или Конечным Связям Box2D метода collisionlisiter

0

Две вещи, которые могут быть неправильно:
1) OP не правильно установить ContactListener после инстанцирования box2d.World
2) категории и биты маски установлены неправильно, поэтому он не вызовет ContactListener

Решение:
1) Поставьте это прямо после создания мира физики , отсутствующего на примере. Это установит ContactListener для вашего box2d.World, поэтому у него будет что-то, что можно вызвать.

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

Пожалуйста, объясняющие, что это неправильно с кодом OP и почему это решает проблему * путем редактирования вашего ответа. * –