2012-01-23 22 views
5

के बिना दो box2d निकायों के प्रारंभिक टक्कर का पता लगाने मैं बहुत की तरह एक संपर्क श्रोता के साथ कुछ सरल box2d निकायों सेटअप:निरंतर टकराव

#import "MyContactListener.h" 

MyContactListener::MyContactListener() : _contacts() { 
} 

MyContactListener::~MyContactListener() { 
} 

void MyContactListener::BeginContact(b2Contact* contact) { 
// We need to copy out the data because the b2Contact passed in 
// is reused. 
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() }; 
_contacts.push_back(myContact); 


b2Body *A = contact->GetFixtureA()->GetBody(); 
b2Body *B = contact->GetFixtureA()->GetBody(); 

NSLog(@"Collision detected!"); 
PLAYSOUND(COLLISION); 

} 

void MyContactListener::EndContact(b2Contact* contact) { 
    MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() }; 
    std::vector<MyContact>::iterator pos; 
    pos = std::find(_contacts.begin(), _contacts.end(), myContact); 
    if (pos != _contacts.end()) { 
     _contacts.erase(pos); 
     } 
} 

void MyContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) { 

} 

void MyContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) { 

} 

और मैं एक ध्वनि खेलने के लिए जब दो शरीर टकरा गए हैं की जरूरत है। हालांकि यह कार्यान्वयन निरंतर टकराव का पता लगाता है ताकि शरीर स्पर्श होने पर ध्वनि बजायी जा सके। Box2d और C++ का मेरा ज्ञान पहले से ही सीमित है, क्या निरंतर टकराव का पता लगाने के बिना एक नया टकराव का पता लगाने का एक आसान तरीका है?

+0

मैं आपको [ट्यूटोरियल] (http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone) के माध्यम से जाने का सुझाव देता हूं ताकि आप एकल टकराव – Marine

+0

का पता लगाने में सक्षम होगा "जब दो निकायों को टक्कर मिलती है" = BeginContact। यह एक निरंतर बात नहीं है, यही कारण है कि इसे 'शुरूआत' कहा जाता है :) – iforce2d

उत्तर

-1

सबसे पहले इस तरह की एक टाइमर सेट ..

[self schedule:@selector(check collision:)]; 

और इस विधि

- (void)tick:(ccTime) dt 
    { 

     for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) 
      { 
      //--------------My contact Listener Start------------------------- 


       std::vector<MyContact>::iterator pos; 

       for(pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); ++pos) 
        { 
         MyContact contact = *pos; 

      // Here get your sprite and make their fixture and check... 

         if ((contact.fixtureA == tempballFixture && contact.fixtureB == _mainballFixture) || 
          (contact.fixtureA == _mainballFixture && contact.fixtureB == tempballFixture)) 
         { 
          if(mainDelegate.music_playing == TRUE) 
          { 
          [[SimpleAudioEngine sharedEngine] playEffect:@"Rock impact.mp3"]; 
          } 
          //-------------collision count for update score value-------- 
        } 
      } 
0

में आप सही मूल विचार है, लेकिन यह कुछ शोधन की जरूरत है।

अपने BeginContact (...) कॉल में, तुम हो:

PLAYSOUND(COLLISION); 

इसके बजाय यहां ध्वनि खेलने में, आप क्या करना चाहिए कतारबद्ध करें इस विशेष जोड़ी के लिए ध्वनि चलाने के लिए कुछ अन्य प्रणाली है। अपने शरीर के उपयोगकर्ता डेटा टैग को कक्षा में पॉइंटर (या इकाइयों का ट्रैक रखने के लिए कुछ अन्य आईडी) पर सेट करें। इसलिए जैसा:

class EntityContactListener : public ContactListener 
{ 
private: 
    GameWorld* _gameWorld; 
    EntityContactListener() {} 

    typedef struct 
    { 
     Entity* entA; 
     Entity* entB; 
    } CONTACT_PAIR_T; 

    vector<CONTACT_PAIR_T> _contactPairs; 

public: 
    virtual ~EntityContactListener() {} 

    EntityContactListener(GameWorld* gameWorld) : 
     _gameWorld(gameWorld) 
    { 
     _contactPairs.reserve(128); 
    } 

    void NotifyCollisions() 
    { 
     Message* msg; 
     MessageManager& mm = GameManager::Instance().GetMessageMgr(); 

     for(uint32 idx = 0; idx < _contactPairs.size(); idx++) 
     { 
     Entity* entA = _contactPairs[idx].entA; 
     Entity* entB = _contactPairs[idx].entB; 

     //DebugLogCPP("Contact Notification %s<->%s",entA->ToString().c_str(),entB->ToString().c_str()); 

     msg = mm.CreateMessage(); 
     msg->Init(entA->GetID(), entB->GetID(), Message::MESSAGE_COLLISION); 
     mm.EnqueueMessge(msg, 0); 

     msg = mm.CreateMessage(); 
     msg->Init(entB->GetID(), entA->GetID(), Message::MESSAGE_COLLISION); 
     mm.EnqueueMessge(msg, 0);   
     } 
     _contactPairs.clear(); 
    } 

    void PreSolve(b2Contact* contact, const b2Manifold* oldManifold) 
    { 

    } 

    // BEWARE: You may get multiple calls for the same event. 
    void BeginContact(b2Contact* contact) 
    { 
     Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData(); 
     Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData(); 
     //DebugLogCPP("Begin Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str()); 
     if(entA->GetGroupID() == entB->GetGroupID()) 
     { // Can't collide if they are in the same group. 
     return; 
     } 

     assert(entA != NULL); 
     assert(entB != NULL); 

     for(uint32 idx = 0; idx < _contactPairs.size(); idx++) 
     { 
     if(_contactPairs[idx].entA == entA && _contactPairs[idx].entB == entB) 
      return; 
     // Not sure if this is needed... 
     if(_contactPairs[idx].entA == entB && _contactPairs[idx].entA == entB) 
      return; 
     } 
     CONTACT_PAIR_T pair; 
     pair.entA = entA; 
     pair.entB = entB; 
     _contactPairs.push_back(pair); 
    } 

    // BEWARE: You may get multiple calls for the same event. 
    void EndContact(b2Contact* contact) 
    { 
     /* 
     Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData(); 
     Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData(); 
     DebugLogCPP("End Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str()); 
     */ 
    } 
}; 

इस के अंतिम भाग नहीं थोड़े समय भले ही एक टकराव होता है के लिए फिर से ध्वनि चलाने है। आप स्टॉपवॉच बनाकर या इकाई अद्यतन चक्रों पर एक निश्चित समय से नीचे गिनकर ऐसा कर सकते हैं।

क्या यह सहायक था?

संबंधित मुद्दे