2012-02-11 17 views
1

我找不到一個奇怪的錯誤。我已經實現了一個ContactListener類來處理我的Android遊戲中的碰撞。在beginContact(Contact arg0)方法中,我可以看到arg0中的兩個物體在那裏,並被推入堆棧。在撥打world.step()之後,我運行自己的handleCollisions()方法,在那裏彈出Contact對象並執行一些遊戲邏輯。但是,偶爾當我彈出一個Contact時,它的一個或兩個物體都是空的。JBox2D Body There There,Now it's null?

Contact與它的身體一起進入堆棧,但它出現空體。我不知道爲什麼會發生這種情況,更重要的是,我無法找到發生這種情況的原因。據我所知,我的其他代碼都沒有去除屍體,但是可能會有副作用,我不知道。這並不總是如此。通常在發生多次碰撞時發生。

任何人有什麼想法可以刪除屍體?或者,有沒有人知道一種方法來追蹤屍體以確定它們何時變爲空?

下面是一些代碼,可能會或可能不會有所幫助:

public class ConcreteContactListener implements ContactListener 
{ 
    private Stack<Contact> contacts; 

    public ConcreteContactListener() 
    { 
     contacts = new Stack<Contact>(); 
    } 

    @Override 
    public void beginContact(Contact arg0) 
    { 
     contacts.push(arg0); 
     System.out.println("push: " + arg0.m_fixtureA.m_body); 
    } 


public int handleCollisions(ArrayList<Ball> balls, World world, ArrayList<Ball> smears, SoundEffects sfx, Combos combos) 
{ 
    int score = 0; 

    while (!contacts.isEmpty()) 
    { 
     Contact contact = contacts.pop(); 
     System.out.println("Contact: " + contact.m_fixtureA.m_body); 
     int a = -1; 
     int b = -1; 

     for (int i = 0; i < balls.size(); i++) 
     { 
      System.out.println("Ball: " + balls.get(i).getBody()); 
      if (contact.m_fixtureA.m_body.equals(balls.get(i).getBody())) 
       a = i; 
      else if (contact.m_fixtureB.m_body.equals(balls.get(i).getBody())) 
       b = i; 
     } 

     ... 

    } 

} 

回答

2

聯繫人合併,並將其重新使用,所以我不建議使用這種方法。相反,我會緩衝只有你需要的信息(這可能是兩個機構)。該jbox2d測試平臺處理這樣說:

首先我們有一個接觸點:

public class ContactPoint { 
    public Fixture fixtureA; 
    public Fixture fixtureB; 
    public final Vec2 normal = new Vec2(); 
    public final Vec2 position = new Vec2(); 
    public PointState state; 
} 

然後我們聽像這樣:

public void beginContact(Contact contact) { 
} 

public void endContact(Contact contact) { 
} 

public void postSolve(Contact contact, ContactImpulse impulse) { 
} 

private final PointState[] state1 = new PointState[Settings.maxManifoldPoints]; 
private final PointState[] state2 = new PointState[Settings.maxManifoldPoints]; 
private final WorldManifold worldManifold = new WorldManifold(); 

public void preSolve(Contact contact, Manifold oldManifold) { 
    Manifold manifold = contact.getManifold(); 

    if (manifold.pointCount == 0) { 
     return; 
    } 

    Fixture fixtureA = contact.getFixtureA(); 
    Fixture fixtureB = contact.getFixtureB(); 

    Collision.getPointStates(state1, state2, oldManifold, manifold); 

    contact.getWorldManifold(worldManifold); 

    for (int i = 0; i < manifold.pointCount 
      && pointCount < MAX_CONTACT_POINTS; i++) { 
     ContactPoint cp = points[pointCount]; 
     cp.fixtureA = fixtureA; 
     cp.fixtureB = fixtureB; 
     cp.position.set(worldManifold.points[i]); 
     cp.normal.set(worldManifold.normal); 
     cp.state = state2[i]; 
     ++pointCount; 
    } 
} 

這很可能是你的目的有點大材小用,因爲它爲每一個聯繫人執行這個邏輯。相反,您可以使用beginContact()endContact()方法,並緩衝一些與您的遊戲更加優化的東西,比如存儲碰撞物體或其他東西。

+0

呵呵。是的,我會嘗試一下,但是,「聯繫人彙集的內容是否會被重複使用」是什麼意思? – 2012-02-12 03:59:23

+0

耶!它現在看起來很有效!非常感謝你! – 2012-02-12 04:16:48

+0

哎呀,我的意思是「重用」。這樣做是爲了避免任何垃圾收集,引擎會多次使用聯繫人對象。別客氣! – 2012-02-12 16:33:14

相關問題