I have created two classes for a rope (made of revolute joints which returns a PhysicsSprite) and a sprite. I am a bit new to contact listeners (not box2d). I want to create a weldjoint on contact of the sprites. I got the contact listener code from Ray Wenderlich's code and modified it a bit. Here's the code below:
MyContactListener.h
Code:
#import "Box2D.h"
#import <vector>
#import <algorithm>
struct MyContact {
b2Fixture *fixtureA;
b2Fixture *fixtureB;
bool operator==(const MyContact& other) const
{
return (fixtureA == other.fixtureA) && (fixtureB == other.fixtureB);
}
};
class MyContactListener : public b2ContactListener {
public:
std::vector<MyContact>_contacts;
MyContactListener();
~MyContactListener();
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);
};
MyContactListener.mm
Code:
#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);
}
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) {
}
my contact listener in the init method of HelloworldLayer.mm:
Code:
// Loop through all of the box2d bodies that are currently colliding, that we have
// gathered with our custom contact listener...
std::vector<b2Body *>toDestroy;
std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); ++pos) {
MyContact contact = *pos;
// Get the box2d bodies for each object
b2Body *bodyA = contact.fixtureA->GetBody();
b2Body *bodyB = contact.fixtureB->GetBody();
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
PhysicsSprite *spriteA = (PhysicsSprite *) bodyA->GetUserData();
PhysicsSprite *spriteB = (PhysicsSprite *) bodyB->GetUserData();
if (spriteA == sprite && spriteB == [rope objectAtIndex:0]) {
b2WeldJointDef weldJointDef;
weldJointDef.Initialize(bodyA, bodyB, bodyA->GetPosition());
weldJointDef.collideConnected = false;
weldJoint = (b2WeldJoint*)world->CreateJoint(&weldJointDef);
}
}
}
I always get the error:
Code:
Thread 1:EXC_BAD_ACCESS(code=2, address=0x4)
pointing to the line:
Code:
for(pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); ++pos)
Please help me out, I've been at it all day.