Тело JBox2D было там, теперь оно нулевое? - PullRequest
1 голос
/ 12 февраля 2012

Странная ошибка, которую я не могу отследить. Я реализовал класс ContactListener для обработки столкновений в моей игре для Android. В методе beginContact(Contact arg0) я вижу, что два тела в arg0 есть и помещаются в стек. Сразу после вызова world.step() я запускаю свой собственный метод handleCollisions(), где я выскакиваю из объектов Contact и выполняю игровую логику. Однако иногда, когда я снимаю Contact, одно или оба его тела равны нулю.

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

        ...

    }

}

1 Ответ

2 голосов
/ 12 февраля 2012

Контакты объединяются и используются повторно, поэтому я не рекомендовал бы использовать этот подход. Вместо этого я бы буферизовал только ту информацию, которая вам нужна (вероятно, это два тела). Тестовый стенд 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() и буферизовать что-то более оптимизированное в вашей игре, например, просто хранить сталкивающиеся тела или что-то в этом роде.

...