How to implement powerUps and other game altering objects in objective-C or cocos2d - iphone

Ok, so I have these powerups that I want to slow/speed up the movement of the other objects in the game for a few seconds.
I have an array of objects that I have a variable called spawnInterval that gets faster and faster as the game progresses, making the ame get harder after a few mins.
But I can't really grasp how to make it so the character in the game will react differently to different objects as in when the fastPowerUp is hit by the character sprite, the spawn interval doesn't change.
And vice versa with the slowPowerUp.
the code I have at the moment is this in a move sequence method that gets called in an update method:
-
(void) updateObstacles:(ccTime)delta{
for (int i = 0; i < 20; i++) {
//int randomizer = CCRANDOM_0_1() * [obstacles count];
//NSLog(#"randomizer: %i",randomizer);
CCSprite* randomObject = [obstacles randomObject];
currentObject = [obstacles indexOfObject:randomObject];
if ([randomObject numberOfRunningActions] == 0) {
[self runObstacleMoveSequence:randomObject withTimer:delta];
break;
}
}
}
-(void) runObstacleMoveSequence:(CCSprite *)object withTimer:(ccTime)delta{
static int time;
//Slowly increase object speed
numObstaclesMoved++;
if (!slowPowerUp && !fastPowerUp) {
time += delta;
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration -= 0.2f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
}
}
}else if (slowPowerUp && !fastPowerUp) {
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration += 3.0f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
if (time >= (delta + 3)) {
slowPowerUp = NO;
obstacleMoveDuration -= 3.0f;
}
}
}
}else if (!slowPowerUp && fastPowerUp) {
if (numObstaclesMoved % 17 == 0 && obstacleMoveDuration > 2.0f) {
obstacleMoveDuration -= 3.0f;
if (spawnInterval > 0.1f) {
[self unschedule:#selector(updateObstacles:)];
[self schedule:#selector(updateObstacles:) interval:spawnInterval];
spawnInterval-=0.1f;
NSLog(#"interval: %f",spawnInterval);
if (time >= (delta + 3)) {
fastPowerUp = NO;
obstacleMoveDuration += 3.0f;
}
}
}
}
CGSize screenSize = [[CCDirector sharedDirector]winSize];
CGPoint aboveScreenPosition = CGPointMake(object.position.x, screenSize.height - object.position.y);
int rotations = (CCRANDOM_0_1()*3) * 360;
float duration = (CCRANDOM_0_1()*5.0f) + 8.0f;
CCMoveTo* move = [CCMoveTo actionWithDuration:obstacleMoveDuration position:aboveScreenPosition];
CCRotateTo* rotate = [CCRotateBy actionWithDuration:duration angle:rotations];
CCSpawn* moveRotate = [CCSpawn actions: move, rotate, nil];
CCCallFuncN* call = [CCCallFuncN actionWithTarget:self selector:#selector(objectAboveScreen:)];
CCSequence* sequence = [CCSequence actions:moveRotate, call, nil];
[object runAction:sequence];
if (time >= (delta + 3)) {
fastPowerUp = NO;
}
}
-(void) objectAboveScreen:(id) sender{
//make sure sender is actually of the right class
NSAssert([sender isKindOfClass:[CCSprite class]], #"sender is not a CCSprite!");
CCSprite* obstacle = (CCSprite*)sender;
//move the back to the bottom of the screen
CGPoint pos = obstacle.position;
CGSize screenSize = [[CCDirector sharedDirector]winSize];
pos.y = (-screenSize.height - [obstacle texture].contentSize.height);
pos.x = CCRANDOM_0_1() * screenSize.width;
obstacle.position = pos;
}
I really just don't know where to go from here... Should I make the powerUps a different class? If so, how would I implement something like this? I really hate trying to ask for someone to solve my question, but I really just can't rack my brain around this and I'm rather new... if it were explained to me, then I know I would be able to implement it in future games on my own...
Thanks in advance, and let me know if more information is needed...

I'd do something like
in the .h file
float speedModifier;
-(void)resetPowerUp;
in the .m
-(void)resetPowerUp
{
speedModifier = 1;
}
wherever you are initializing the level
[self resetPowerUp];
upon collision with powerup:
speedModifier = 2;
[self performSelector:#selector(resetPowerUp) withObject:nil afterDelay:5];
then wherever you are moving whatever it is which speed should be effected by the powerup mode, multiply the speed of the animation (or divide the duration it takes for it to get wherever it's going) by speedModified
hope that helps

Related

Sprites are disappear after some time

Here some code for Add sprite for Enemies.....
_robbers = [[CCArray alloc] initWithCapacity:kNumAstroids];
for (int i = 0; i < kNumAstroids; ++i) {
CCSprite *asteroid = [CCSprite spriteWithSpriteFrameName:#"robber.png"];
asteroid.visible = NO;
[_batchNode addChild:asteroid];
[_robbers addObject:asteroid];
}
And in Update method ........
double curTime = CACurrentMediaTime();
if (curTime > _nextRunemanSpawn) {
float randSecs = [self randomValueBetween:0.20 andValue:1.0];
_nextRunemanSpawn = randSecs + curTime;
float randY = [self randomValueBetween:80 andValue:80];
float randDuration = [self randomValueBetween:4.5 andValue:4.5];
float randDuration1 = [self randomValueBetween:1.0 andValue:1.0];
CCSprite *asteroid = [_robbers objectAtIndex:_nextRobber];
_nextRobber++;
if (_nextRobber >= _robbers.count) {
_nextRobber = 1;
}
[asteroid stopAllActions];
asteroid.position = ccp(winSize.width +asteroid.contentSize.width / 2 , randY);
asteroid.visible = YES;
[asteroid runAction:[CCSequence actions:[CCMoveBy actionWithDuration:randDuration position:ccp(-winSize.width-asteroid.contentSize.width, 0)],
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)],nil]];
All Sprites are Move from right to left in screen
when Sprite crosses the middle of the screen it automatically disappear
what is the reason for this problem ??
I agree with the previously mentioned statement from LearnCocos2D. It is also possible that you are adding multiple objects and reaching the end of the capacity in the line
_robbers = [[CCArray alloc] initWithCapacity:kNumAstroids];
If you try to spawn more objects than whatever number you have specified for kNumAsteroids it will remove the oldest object and use the new one in its place. I.e. if kNumAsteroids is 5, you have 5 on the screen and then add a sixth, 1 will become 6 and its position will be whatever you set it to.

Show UIImageView in a random position on the screen

I am developing a game that uses the gyroscope to keep enemies in relatively the same place, with the following code:
if([motionManager isGyroAvailable])
{
[motionManager setGyroUpdateInterval:0.05];
[motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMGyroData *gyroData, NSError *error)
{
valueX3 = gyroData.rotationRate.y* 50;
valueY3 = gyroData.rotationRate.x* 50;
int newX3 = (int)(enemyufoG.center.x +valueY3);
int newY3 = (int)(enemyufoG.center.y -valueX3);
CGPoint newCenter2 = CGPointMake(newX3, newY3);
enemyufoG.center = newCenter2;
valueX2 = gyroData.rotationRate.y* 50;
valueY2 = gyroData.rotationRate.x* 50;
int newX2 = (int)(enemyufoR.center.x +valueY2);
int newY2 = (int)(enemyufoR.center.y -valueX2);
CGPoint newCenter = CGPointMake(newX2, newY2);
enemyufoR.center = newCenter;
valueX = gyroData.rotationRate.y* 50;
valueY = gyroData.rotationRate.x* 50;
int newX = (int)(enemyAlien.center.x +valueY);
int newY = (int)(enemyAlien.center.y -valueX);
CGPoint newCenter3 = CGPointMake(newX, newY);
enemyAlien.center = newCenter3;
}];
}
Once you shoot an enemy that is in the crosshairs of the gun, it hides the UIImageView, then uses NSTimer to call a different method that shows it again. I would like to have the enemies reappear in random positions on the screen.
CGPoint pos = enemyAlien.center;
if ((pos.x > 254) && (pos.x < 304) && (pos.y > 140) && (pos.y < 160 && _ammoCount != 0))
{
enemyAlien.hidden = YES;
[dangerBar setProgress:dangerBar.progress-0.10];
_killCount = _killCount+3;
[killCountField setText: [NSString stringWithFormat:#"%d", _killCount]];
timer = [NSTimer scheduledTimerWithTimeInterval: 4.0
target: self
selector: #selector(showAlien)
userInfo: nil
repeats: NO];
}
- (void) showAlien {
enemyAlien.hidden = NO;
}
When I try and use enemyAlien.center = enemyAlien.center + arc4random()%100; above enemyAlien.hidden = NO, I get the following error:
'Invalid operands to binary expression ('CGPoint (aka 'struct CGPoint') and 'unsigned int').
You're trying to add an integer to a cgpoint.
try this.
enemyAlien.center = CGPointMake(enemyAlien.center.x + (arc4random()%100),enemyAlien.center.y + (arc4random()%100));
although this will only move the alien in a diagonal direction. You should probably change it to the following for a better experience.
enemyAlien.center = CGPointMake((arc4random()%SCREEN_WIDTH),(arc4random()%SCREEN_HEIGHT));
where SCREEN_WIDTH and SCREEN_HEIGHT are the dimensions of your playing field.

Animating sequence of images in cocos2d

i have this code to show animation of a image
-(void) blink:(ccTime) delta {
animateblink ++; //adds 1 every frame
if (animateblink <= 6 ) { //if we included frames to show for breaking and the current frame is less than the max number of frames to play
if (animateblink < 6) {
[sprite setTexture:[[CCSprite spriteWithFile:[NSString stringWithFormat:#"%#_blinkk00%i.png", baseImageName,animateblink]] texture]];
[self unschedule:_cmd];
[self schedule:#selector(openEyes:) interval:0.1f];
[self schedule:#selector(moveSprite:) interval:0.1f];
}
}
}
i have 6 images of animating like
dragonimage_blinkk001,dragonimage_blinkk002,dragonimage_blinkk003,dragonimage_blinkk004,dragonimage_blinkk005,dragonimage_blinkk006 like that
i put two methods,
1: for animation time
2: for movement of the image
the code is
-(void) openEyes:(ccTime) delta {
[sprite setTexture:[[CCSprite spriteWithFile:[NSString stringWithFormat:#"%#.png", baseImageName]] texture]];
[self unschedule:_cmd];
int blinkInterval = (arc4random() % 6) + 1; // range 3 to 8
[self schedule:#selector(blink:) interval:blinkInterval];
}
-(void)moveSprite:(ccTime)delta
{
movementCounter ++;
if (movementCounter == 1000) {
[self unschedule:_cmd];
}
else
{
spriteimagename.position = ccp(spriteimagename.position.x+10,spriteimagename.position.y);
}
}
but on the first method the animation time is not correct,there is a lot of delay of animation,i just want to show animation of the images randomly and fast,its a dragon flying animation.
my sec on method is not at all working,i didn't get any movement of that image.
i hope you understand my issue.how to solve the above two method issues.
Thanks in advance.
Quick solution is to add frameIndex member in cocos2d CCSpriteFrame class. i don't know is that allowed to change. But it works fine.
#interface CCSpriteFrame : NSObject <NSCopying>
{
int frameIndex;
....
}
//Here in code initialize frames with unique index
CCAnimation* animation;
NSMutableArray *animFrames2 = [NSMutableArray array];
for( int i=1;i<=15;i++)
{
CCSpriteFrame *frame = [cache spriteFrameByName:[NSString stringWithFormat:#"ActerSmash_%d.png",i]];
frame.frameIndex = (int)i;
[animFrames2 addObject:frame];
}
animation = [CCAnimation animationWithFrames:animFrames2];
CCAnimate *action = [CCAnimate actionWithDuration:ACTER_SMASH_SPEED animation:animation restoreOriginalFrame:YES];
action.tag = kTagAnimationSmashAnim ;
mActer.AnimSmash = action;
//Checking frame Index
CCAnimate *anim = mActer.AnimSmash ;
for(CCSpriteFrame *frame in anim.animation.frames)
{
if([mActer isFrameDisplayed:frame] ) )
{
if(frame.frameIndex == 5 )
{
//Do something..
}
}
}

How do I get a particle effect to follow my sprite in cocos2d?

I want a snow particle effect to follow my sprite and I tried some methods but all that ends up happening is the snow will just stay still instead of following. I did this one tutorial (will post as soon as I find it) thats shows how it do it with fire but didn't work out at all. Any tutorials or suggestions will be appreciated. I believe i have to add some kind of code to the snippet part where it says create enemy off screen.
[self schedule:#selector(gameLogicboss:) interval:180 ];
[self schedule:#selector(updateboss:)];
-(void)addTarget1 {
Boss *target1 = nil;
if ((arc4random() % 2) == 0) {{
target1 = [WeakAndFastBoss boss];
}} else {
target1 = [WeakAndFastBoss boss];
}
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target1.contentSize.height/2;
int maxY = winSize.height - target1.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target1.position = ccp(winSize.width + (target1.contentSize.width/2), actualY);
[self addChild:target1 ];
// Determine speed of the target
int minDuration = target1.minMoveDuration;
int maxDuration = target1.maxMoveDuration;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-target1.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(spriteMoveFinished:)];
[target1 runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
target1.tag = 1;
[_targets addObject:target1];
}
-(void)gameLogicboss:(ccTime)dt {
[self addTarget1];
iterations_++;
}
- (void)updateboss:(ccTime)dt {
CGRect projectileRect = CGRectMake(projectile.position.x - (projectile.contentSize.width/2), projectile.position.y - (projectile.contentSize.height/2), projectile.contentSize.width, projectile.contentSize.height);
BOOL bossHit = FALSE;
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target1 in _targets) {
CGRect target1Rect = CGRectMake(target1.position.x - (target1.contentSize.width/2), target1.position.y - (target1.contentSize.height/2), target1.contentSize.width, target1.contentSize.height);
if (CGRectIntersectsRect(projectileRect, target1Rect)) {
//[targetsToDelete addObject:target];
bossHit = TRUE;
Boss *boss = (Boss *)target1;
boss.hp--;
if (boss.hp <= 0) {
_score ++;
[targetsToDelete addObject:target1];
}
break;
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
_projectilesDestroyed++;
if (_projectilesDestroyed > 2) {
}
}
if (bossHit) {
//[projectilesToDelete addObject:projectile];
[[SimpleAudioEngine sharedEngine] playEffect:#"explosion.caf"];
}
[targetsToDelete release];
}
-(void)spriteMoveFinishedboss:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:#"You Lose"];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
if (sprite.tag == 1) { // target
[_targets removeObject:sprite];
} else if (sprite.tag == 2) { // projectile
[_projectiles removeObject:sprite];
}
}
I Have found this, at CCParticleSystem.h
/** #typedef tCCPositionType
possible types of particle positions
/
typedef enum {
/* Living particles are attached to the world and are unaffected by emitter repositioning. */
kCCPositionTypeFree,
/** Living particles are attached to the world but will follow the emitter repositioning.
Use case: Attach an emitter to an sprite, and you want that the emitter follows the sprite.
*/
kCCPositionTypeRelative,
/** Living particles are attached to the emitter and are translated along with it. */
kCCPositionTypeGrouped,
you should set it like
myparticleSystem.positionType=kCCPositionTypeGrouped;
Hope it helps.
You don't need to update the particle emitter's position with the sprite.
You can add a particle system to the sprite as a child.
The particle system does need to be typed as such:
CCParticleSystem * booster = [CCParticleSystem particleWithFile:#"boosterParticles.plist"];
//customize your particles' options
//assuming you have a sprite defined as _motherShip
[_motherShip addChild:booster];
/*
* now that the particles are the _motherShip's child, you must remember
* to set the position relative to the mothership's origin...
*/
particles.position = ccp(15,0);
...So now whenever _motherShip.position changes, the booster will follow. It will even rotate with the ship.
Very simple logic without getting into code:
I spawn a sprite and give it a location (x, y).
For each sprite, I also spawn a CCParticleSystem, give it the required particle type, spawn rates etc.
The CCParticleSystem location is now set to be the same (x,y) location as the sprite, and it should get updated as the sprite's (x,y) location is update.
As the sprite and the CCParticleSystem move around, this location (x, y) is getting updates constantly at random in your schedule method per the interval step time.
Hope that makes sense.
I do this
vehicleParticleSystem = [CCParticleSystemQuad particleWithFile:#"vehicleParticle.plist"];
vehicleParticleSystem.position = ccp(_ship.position.x - _ship.contentSize.width/3, _ship.position.y - _ship.contentSize.height/3);
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
vehicleParticleSystem.scale = 0.5;
}
[self addChild:vehicleParticleSystem z:-1];
and update its position with this
- (void) updateParticleSystem:(ccTime)dt {
vehicleParticleSystem.position = ccp(_ship.position.x - _ship.contentSize.width/3, _ship.position.y - _ship.contentSize.height/3);
}
which is called in the -(void) update:(ccTime)dt method.
The ship is moved by the user via a joypad.
hope this helps. The positioning for the particle is slightly behind the vehicle for an engine effect.
Did you tried to update your particle position taking advantage of the update method?
I'm doing something like the following lines in one of my games and it works as I think you expect
-(void) update:(CCTime)delta{
_sprite.position = CGPointMake(newXPosition, newYPosition);
_fire.position = CGPointMake(_sprite.position.x, _sprite.position.y);
}
I hope it helps!

Game crashes when I try to destroy a b2Body, what should I do?

"Assertion failed: (m_bodyCount < m_bodyCapacity), function Add, file libs/Box2D/Dynamics/b2Island.h, line 65."
That is what it the crash leaves in the console.
[self removeChild:(CCSprite*)body->GetUserData() cleanup:YES];
body->SetTransform(b2Vec2(30, 30), 0); //moving the body out of the scene so it doesnt collide anymore!
world->DestroyBody(body);
I think im doing the right stuff..
#property (nonatomic, assign) b2Body *body;
Here is how i "make it" a property
I dont understand why it doesnt work, "body" is a proper pointer because I can retrieve infromation from the bodys UserData like tags that are set in the creatin of the body, so that shouldnt be a problem.. Do anyone know whats wrong with my code?
Thank you.
Edited in:
-(void) tick: (ccTime) dt //Main loop
{
if (ballFired) {
Magnet *aMagnet = [magnetArray objectAtIndex:0];
world->DestroyBody(aMagnet.body); //It crashes here!
}
int32 velocityIterations = 8;
int32 positionIterations = 1;
// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
world->Step(dt, velocityIterations, positionIterations);
//Iterate over the bodies in the physics world
for (b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite *myActor = (CCSprite*)b->GetUserData();
myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b>GetPosition().y * PTM_RATIO);
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
Isnt this outside the world step?
Edit 2:
ContactListener::ContactListener(){};
void ContactListener::BeginContact(b2Contact* contact)
{
// Box2d objects that collided
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
CCSprite* actorA = (CCSprite*) fixtureA->GetBody()->GetUserData();
CCSprite* actorB = (CCSprite*) fixtureB->GetBody()->GetUserData();
if(actorA == nil || actorB == nil) return;
b2WorldManifold* worldManifold = new b2WorldManifold();
contact->GetWorldManifold(worldManifold);
Kollisjon *kollisjon = [Kollisjon sharedKollisjon];
if (actorA.tag == 1) {
NSLog(#"OK1");
kollisjon.kollidertBody = fixtureB->GetBody();
kollisjon.world->DestroyBody(kollisjon.kollidertBody); //Isnt this ok?
}
else if (actorB.tag == 1) {
NSLog(#"OK2");
kollisjon.kollidertBody = fixtureA->GetBody();
kollisjon.world->DestroyBody(kollisjon.kollidertBody); //Isnt this ok?
}
}
Is it not outside the timestep? Please help me here...
Thank you
You must scan for contacts, store all contacts in an array, and then AFTER all contacts have been checked, you remove your bodies.
Checking for contacts:
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();
// Rocket explosion rect
if(bodyA->GetUserData() == NULL)
{
NSLog(#"NULL collision detected. (BODY A)");
hasDoneRocketCollisions = YES;
CCSprite *sprite = (CCSprite*) bodyB->GetUserData();
if(sprite.visible == NO) continue;
if(sprite.tag >= 200 && sprite.tag < 300)
{
index = sprite.tag - 200;
if([spriteTracker containsObject:sprite]) continue;
[spriteTracker addObject:sprite];
bodiesToKill[counter] = bodyB;
[enemyChargerIsAlive replaceObjectAtIndex:(int)(sprite.tag-200) withObject:[NSNumber numberWithInt:0]];
[ParticleController spawnExplosion:sprite.position inParent:currentDefaultNode];
}
else if(sprite.tag >= 300 && sprite.tag < 400)
{
index = sprite.tag - 300;
if([spriteTracker containsObject:sprite]) continue;
[spriteTracker addObject:sprite];
bodiesToKill[counter] = bodyB;
[enemyShooterIsAlive replaceObjectAtIndex:(int)(sprite.tag-300) withObject:[NSNumber numberWithInt:0]];
[ParticleController spawnExplosion:sprite.position inParent:currentDefaultNode];
counter++;
}
}
}
Later in your method after all contacts have been checked:
b2Body *dyingBody;
for(int i = 0; i < counter; i++)
{
CCSprite *dyingSprite;
dyingSprite = [spriteTracker objectAtIndex:i];
dyingSprite.visible = NO;
// Is player projectile
if(dyingSprite.tag >= 100 && dyingSprite.tag < 200)
{
CCParticleSystemQuad *dyingParticle;
dyingParticle = [particlesToKill objectAtIndex:particleIndex];
particleIndex++;
[dyingParticle stopSystem];
dyingBody = bodiesToKill[i];
dyingBody->SetActive(false);
[ParticleController spawnExplosion:dyingSprite.position inParent:currentDefaultNode];
[AudioController playExplosion];
dyingSprite.visible = NO;
if([_player currentShotType] == 1)
{
rocketHitBody->SetTransform(b2Vec2(dyingSprite.position.x/PTM_RATIO, dyingSprite.position.y/PTM_RATIO), 0.0);
rocketHitBody->SetActive(true);
}
}
}
Take note that these are just random chunks of code I have copy and pasted in. They are for example only and may only confuse you if you try to read them as exact instructions.
The point here is: You can not remove a body while it is being accessed by the step or contact listener. Finish using the contact listener and then remove your bodies.