Collision Listeners Cocos 2Dx

# ifndef _COLLISION_LISTENER_   
# define _COLLISION_LISTENER_   
# include <vector>   
# include "Box2D\Box2D.h"   
#include "Box2D\Dynamics\b2WorldCallbacks.h"   

class CollisionListener : public b2ContactListener   
{        
   std::vector<b2Contact*> _contacts;   

   public:        
   /// Called when two fixtures begin to touch.        
   virtual void BeginContact(b2Contact* contact);
   
   /// Called when two fixtures cease to touch.        
   virtual void EndContact(b2Contact* contact);

   //explicitly called from main every frame         
   void ResolveContacts();        

   bool ResolveContact( b2Contact * contact);   

};
# endif 

.cpp file

#include "CollisionListener.h"
#include "Physics/PhysicsSprite.h"   
void CollisionListener::BeginContact( b2Contact* contact )   
{        
   std::vector<b2Contact*>::iterator iter = std::find(_contacts.begin(), _contacts.end(), contact);        
   if (iter != _contacts.end())        
   {             
      _contacts.erase(iter);        
   }        
   _contacts.push_back(contact);   
}   
void CollisionListener::EndContact( b2Contact* contact )   
{        
   std::vector<b2Contact*>::iterator iter = _contacts.begin();        
   iter = std::find(_contacts.begin(), _contacts.end(), contact);        
   if( iter != _contacts.end())        
   {             
      _contacts.erase(iter);        
   }   
}   

//must be called every frame
void CollisionListener::ResolveContacts()   
{        
   std::vector<b2Contact*>::iterator iter;        
   for (iter = _contacts.begin(); iter != _contacts.end();)        
   {             
      if(ResolveContact(*iter))             
      {                  
         iter  = _contacts.erase(iter);             
      }             
      else             
      {                  
         ++iter;             
      }        
   }   
}   

bool CollisionListener::ResolveContact( b2Contact * contact)   
{        
   PhysicsSprite * phySpriteA;        
   PhysicsSprite * phySpriteB;        
   b2Body * body = contact->GetFixtureA()->GetBody();        

   if(body != NULL && body->GetUserData() != NULL)        
   {             
    // do resolve             
     phySpriteA = (PhysicsSprite*)(body->GetUserData());         
   }        
   else        
  {             
    return true;        
  }        

   body = contact->GetFixtureB()->GetBody();        
   if(body != NULL && body->GetUserData() != NULL)        
   {             
     //do resolve             
     phySpriteB = (PhysicsSprite*)(body->GetUserData());         
   }        
   else        
  {             
     return true;        
  }        

//In your custom physics sprite class, you must have a GetObjectId() to determine the object 
  phySpriteA->CollidesWith(phySpriteB->GetObjectId(), phySpriteB);        
  phySpriteB->CollidesWith(phySpriteA->GetObjectId(), phySpriteA);        
  return true;   
}  
 

Initialize listener in main.cpp

 //initialize Collision listener        
_collisionListener = new CollisionListener();

//your physics world
 PhysicsEnvironment::getWorld()->SetContactListener(_collisionListener);  
//on update do this
_collisionListener->ResolveContacts(); 
Now whenever two objects collide the function collides with will be triggered in both the classes. Lets see an example from player class

Player.h

//virtual fns        
virtual void CollidesWith(ENUM_OBJECT object, PhysicsSprite * phySprite);  

Player.cpp

void Player::CollidesWith( ENUM_OBJECT object, PhysicsSprite * phySprite)  
{        
   switch (object)        
   {        
      case e_Crate:             
      {                
          //do add your logic here - when player collides with crate           
      }             
      break;   
     
     default:             
     break;        
    }   
}  

All the stuffs mentioned here are not explained in detail. If required put a comment, will reply asap. Happy Coding 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *