Войти
Box2DФорумОбщее

Box2D обработка коллизий (ContactListener)

#0
1:12, 17 янв. 2012

Столкнулся с проблемой обработки коллизий в Box2D используя ContactLsitener.
Нашел туториал как применяются и обрабатываться коллизии (http://www.iforce2d.net/b2dtut/collision-callbacks).
Но проблема в том что не получается использовать метод m_world->SetContactListener(...).
Использую Box2D 2.2.1, в коде пытаюсь использовать SetContactListener:
...
b2World world(gravity);
word->...

но world ничего не выдает..

Дайте пример кто нибудь, обработки коллизий на Box2D 2.2.1


#1
1:38, 17 янв. 2012

у тебя world - структура, ты её разыменовываешь как указатель. вообще это тебе не java и не c# - если intellisense чего-то не показывает, это не значит ровным счётом ничего.

#2
2:35, 17 янв. 2012

малость разобрался, но никак не получается обрабатывать столкновения, не понимаю как вообще это делается
смотрел документацию, форумы, туториалы -  так там или старая версия box2d или не совсем до конца показано как все должно выглядеть..

#3
10:17, 17 янв. 2012

SLICK
Создаешь файл ContactL.h

#include <Box2D/Box2D.h>
#include <Box2D/Dynamics/Contacts/b2Contact.h>

class MyContactListener : public b2ContactListener
{

public:
  //Эта функция вызывается когда два тела начинают пересекаться
  void BeginContact(b2Contact* contact){};
  
  //Эта когда два тела перестают пересекаться
  void EndContact(b2Contact* contact){};
  

  void PreSolve(b2Contact* contact,const b2Manifold* oldManifold)
  {
  const b2Manifold* manifold = contact->GetManifold();

  b2Fixture* fixtureA = contact->GetFixtureA();
  b2Fixture* fixtureB = contact->GetFixtureB();

  b2WorldManifold worldManifold;
  contact->GetWorldManifold(&worldManifold);

  b2Body* bodyA = fixtureA->GetBody();
  b2Body* bodyB = fixtureB->GetBody();
  };


  void PostSolve(b2Contact* contact,const b2ContactImpulse* Impulse){};
};

в основном коде инкулдим. и создаем :

MyContactListener *contactListener;

contactListener = new MyContactListener();
world->SetContactListener(contactListener);

Ну а дальше сам поймешь.

#4
18:53, 17 янв. 2012

fzr125, Работает!=) Большое Спасибо! Теперь разобрался!

#5
11:18, 7 фев. 2012

почему у меня вместо столкновения между кругом и линией считывается столкновение между ограничивающими прямоугольниками? код вроде такойже, что сверху.

#6
16:00, 7 фев. 2012

krushserg
PostSolve
PreSolve
EndContact
BeginContact
Почитай в мануале про эти функции - где и когда они будут вызваны.

#7
17:17, 8 фев. 2012

fzr125
Это все хорошо, можешь мне подсказать на счет toDestroy функции.
Ситуация у меня такая,  при соприкосновении двух тел мне надо 1 удалить, по мануалу нашел функции вообщем у меня так все выглядит

std::vector<b2Body *>toDestroy;
    std::vector<MyContact>::iterator pos;
    for(pos = _contactListener->_contacts.begin();
        pos != _contactListener->_contacts.end(); ++pos){
        MyContact contact = *pos;
        
        b2Body *bodyA = contact.fixtureA->GetBody();
        b2Body *bodyB = contact.fixtureB->GetBody();
        
        if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
            CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
            CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();
            
            if (spriteA.tag == 1 && spriteB.tag == 6) {
                NSLog(@"GO1");
                mainBody->SetLinearVelocity(b2Vec2(0.f,0.f));
                
                
                if (std::find(toDestroy.begin(), toDestroy.end(), bodyB) 
                    == toDestroy.end()) {
                    toDestroy.push_back(bodyB);
                }
            }
            
            
            std::vector<b2Body *>::iterator pos2;
            for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
                b2Body *body = *pos2;     
                if (body->GetUserData() != NULL) {
                    CCSprite *spriteC = (CCSprite *) body->GetUserData();
                    [self removeChild:spriteC cleanup:YES];
                }
                 world->DestroyBody(body);
            }
    
    }

  код удаления проходит нормально но при следущей итерации падает на строчке

b2Body *bodyA = contact.fixtureA->GetBody();

понять не могу почему(

Прошло более 12 месяцев
#8
1:14, 5 фев. 2013

Разбирался с такой же проблемой... Вообщем удалять в контактлистенере нельзя.... Отметь флажками то что хочешь удалить и удаляй где-нибудь в другом месте...

Прошло более 10 месяцев
#9
20:25, 20 дек. 2013

я делал так, мб и не верно.
Но когда ты удаляешь обьект , то ты нарушаешь цепочку
next();
если ты запомнишь слд обьект в tmp переменную, а потом ее просто востанови
то тогда не будет у тя краша.

Box2DФорумОбщее

Тема в архиве.