Hey guys, newbie programmer here and I've been banging my head against the wall for the past six hours trying to figure this out so hopefully someone knows how to get around this. I've been trying to code a physics engine in box2D for a game I'm developing and it's been going fine until I've had to start working with collisions. But it's not the collisions thats the problem, I've implemented the contact listener and programmed the update method appropriately and when my two object's collide they do exactly what I want. The "player" hits the object and it immediately explodes, de-spawning and shooting the player backwards.
The problem is I don't want it to happen immediately. I want the item to wait a little before blowing up, giving the player a chance to get away. Like a bomb that will turn red if the user gets to close and after something like three seconds of the player standing near it, it will explode. I can't for the life of me figure out how to do this, I've tried NStimers, scheduling different methods, performselector with delay, and even sequences to stall it at first but each one of these either crash the app or cause it to hang. I think the problem might be that the collision detection itself is
in the gamelogic update code. It also doesn't help that NStimers and the a performselector code can only take objects as parameters
Here's basically what it looks like with the immediate explosion:
-(void) update: (ccTime)delta
{
// The number of iterations influence the accuracy of the physics simulation. With higher values the
// body's velocity and position are more accurately tracked but at the cost of speed.
// Usually for games only 1 position iteration is necessary to achieve good results.
float timeStep = 0.03f;
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(timeStep, velocityIterations, positionIterations);
// for each body, get its assigned sprite and update the sprite's position
for (b2Body* body = world->GetBodyList(); body != nil; body = body->GetNext())
{
CCSprite* sprite = (CCSprite*)body->GetUserData();
if (sprite != NULL)
{
// update the sprite's position to where their physics bodies are
sprite.position = [self toPixels:body->GetPosition()];
float angle = body->GetAngle();
sprite.rotation = CC_RADIANS_TO_DEGREES(angle) * -1;
}
b2Vec2 slow = body->GetLinearVelocity();
slow.x = slow.x * -.0025;
slow.y = slow.y * -.0025;
body->ApplyLinearImpulse(slow, body->GetPosition());
}
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();
b2Vec2 nails = bodyA->GetPosition();
b2Vec2 nails2 = bodyB->GetPosition();
CGPoint nail = ccpMult(CGPointMake(nails.x,nails.y), 32);
if(fabs(nails.x - nails2.x) < 1 && fabs(nails.y - nails2.y) <1){
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;
b2Vec2 nails = body->GetPosition();
CGPoint nail = ccpMult(CGPointMake(nails.x,nails.y), 32);
if (body->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *) body->GetUserData();
sprite.opacity = (255 - 100);
[self removeChild:sprite cleanup:YES];
[self launchBomb:nail:NO]; //actual explosion
[self explode:nail]; // particle effect
}
world->DestroyBody(body);
}
}
If there was some way to change that last part so I could have the collision and start a process to build up to an explosion that would be amazing because I'm so confused now.