Реализация проблемы с b2ContactListener (box2d)

#cocos2d-iphone #box2d

#cocos2d-iphone #box2d

Вопрос:

Я читал руководство box2d и увидел, что межкадровые контакты могут быть обнаружены только с помощью b2ContactListener.

Я создал класс ActorListener (все активные объекты мира являются действующими лицами)

 class ActorListener : public b2ContactListener
{ 
    public :
    ActorListener();
    ~ActorListener();

    virtual void BeginContact(b2Contact* contact);
    virtual void EndContact(b2Contact* contact);
    virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);    
    virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
};
 

И добавил его в мой мир, когда игра инициализируется:

     Listener = new ActorListener();
    world->SetContactListener(Listener);
 

Но как только происходит столкновение, я получаю сообщение об ошибке в b2Contact.cpp

     if (wasTouching == false amp;amp; touching == true amp;amp; listener)
{
    listener->BeginContact(this); //EXC_BAD_ACCESS
}
 

Есть какие-нибудь идеи? Я делаю это неправильно?

Ответ №1:

Код установки правильный. Я бы предложил некоторые изменения в классе ActorListener:

 class ActorListener : public b2ContactListener
{ 
    private :
    void BeginContact(b2Contact* contact);
    void EndContact(b2Contact* contact);
    void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);    
    void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
};
 

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

Тем не менее, если вам не нужен конструктор или деструктор, вы можете их опустить. Вам также следует удалить ключевое слово virtual, поскольку вы предоставляете конкретную реализацию и не планируете создавать подклассы ActorListener (верно?). Невиртуальные методы немного быстрее. Наконец, методы должны быть частными, потому что их будет вызывать только Box2D, никакому другому коду не должно быть разрешено вызывать методы в классе ActorListener. Если вы получаете ошибки компиляции после внесения этих изменений, это может быть связано с сбоем.

Сбой указывает на то, что, по всей вероятности listener , файл больше не указывает на действительную память, т. Е. Он был освобожден. Другая возможность может заключаться в том, что фактический код в beginContact вызывает сбой, но по какой-то причине отладчик останавливается на строке, выполняющей вызов. Возможно, вы захотите установить точку останова в beginContact. И добавьте реализацию beginContact к вашему вопросу.

Наконец, хотя я предполагаю, что компилятор проверит это, установлено ли расширение файла файла реализации ActorListener равным .mm?

Комментарии:

1. «Другая возможность может заключаться в том, что фактический код в beginContact вызывает сбой». Вот и все. Я выполнил недопустимое приведение в этом методе. Спасибо и за другие советы. Выглядит намного чище.

2. Спасибо за то, что вы такой хороший вкладчик. Я предварительно заказал вашу книгу на Amazon, так что, надеюсь, мне не придется слишком много публиковать здесь 🙂