Reputation: 1345
In my spritekit game I am creating Stone randomly through update method. Here is my code for random creation of stone
//Create random island
-(void)createRandomStone:(NSMutableArray *)imageArray
{
int getRandomNumberCoordinate = [self getRandomNumberBetween:(int)0 to:(int)768];
int getRandomStoneImage = [self getRandomNumberBetween:0 to:(int)([imageArray count] - 1)];
NSLog(@"Stone Image name = %d", getRandomStoneImage);
SKSpriteNode *createStone = [SKSpriteNode spriteNodeWithTexture:[imageArray objectAtIndex:getRandomStoneImage]];
if((getRandomNumberCoordinate + createStone.size.height / 2) > 768 )
createIsland.position = CGPointMake(_myScreenSize.width + createStone.size.width, 768 - createStone.size.height / 2);
else if((getRandomNumberCoordinate - createStone.size.height / 2) < 0 )
createStone.position = CGPointMake(_myScreenSize.width + createStone.size.width, 0 + createIsland.size.height / 2);
else
createStone.position = CGPointMake(_myScreenSize.width + createStone.size.width, getRandomNumberCoordinate);
createStone.name = @"Stone";
createStone.zPosition = 3;
[self addChild:createStone];
//Apply physics on the Stone
createStone.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: CGSizeMake(createStone.size.width - createStone.size.width / 4, createStone.size.height - createStone.size.height / 6)];
createStone.physicsBody.categoryBitMask = CollisionTypeStone;
createStone.physicsBody.contactTestBitMask = CollisionTypeMan;
createStone.physicsBody.usesPreciseCollisionDetection = YES;
createStone.physicsBody.collisionBitMask = 0;
}
Stones are moving from the coordinate 1024 to 0 and if any stone cross the 0 coordinate the the stone will remove by using the code
-(void)updateStonePosition:(NSString *)whichDirection andMoveAmount:(float)speed
{
for (SKNode* node in self.children)
{
if([node.name isEqualToString:@"Stone"])
{
node.position = CGPointMake(node.position.x - speed, node.position.y);
if(node.position.x < -node.frame.size.width / 2)
[node removeFromParent];
}
}
}
Both of the above two methods are calling from the update method. And if the man hit by any 5 stone then the game will again reload. The reloading code is:
[self.view presentScene:[[MyScene alloc] initWithSize:self.size] transition:[SKTransition doorsCloseHorizontalWithDuration:0.5f]];
the game is reloaded but after few second an error message shows EXC_BAD_ACCESS(code=2, address = 0x0) on the line
SKSpriteNode *createStone = [SKSpriteNode spriteNodeWithTexture:[imageArray objectAtIndex:getRandomStoneImage]];
Please help. Thanks in advance.
Upvotes: 5
Views: 491
Reputation: 2320
If your imageArray is not nil, and you've got more than one item, and it's still crashing, then you could be experiencing one of SpriteKit's bugs with the physics bodies (or skshapenodes elsewhere). See this thread..: https://stackoverflow.com/a/25007468/557362
I've had this sort of problem myself, and I've got code in my common scene base class to clean up scenes, but I don't use physics bodies - which could be your problem (see link).
-(void)cleanUp
{
[self cleanUpChildrenAndRemove:self];
}
- (void)cleanUpChildrenAndRemove:(SKNode*)node {
for (SKNode *child in node.children) {
[self cleanUpChildrenAndRemove:child];
}
[node removeFromParent];
}
I also found that crashes were happening on transitions - and that if I delayed cleanup for a second after transition (and kept the scene alive just long enough), I had no crashes. E.g.
SKTransition* doors = [SKTransition fadeWithDuration:0.75];
[[self view] presentScene:newscene transition:doors];
SKNode* dummynode = [SKNode node];
// wait for the transition to complete before we give up the reference to oldscene
[dummynode runAction:[SKAction waitForDuration:2.0] completion:^{
// failing to clean up nodes can result in crashes... nice.
[((MySceneBaseClass*)oldscene) cleanUp];
}];
[newscene addChild:dummynode];
Upvotes: 0
Reputation: 451
To me, and with the code/information you are providing, it seems that when your scene is reloaded the array you are passing to "createRandomStone:" is nil.
Try checking for nil before calling the method:
if (imageArray != nil) {
// call createRandomStone
} else {
NSLog(@"imageArray is nil")
}
see if that helps identifying the root cause of the error.
Upvotes: 1
Reputation: 4151
I was also trying to find out some information how to reset/restart the SpriteKit game but I wasn't successful. I didn't spend enough time to find out why this is happening in my case, probably should try to do some cleaning before the transition happens like removing all actions and maybe all nodes...but I found a workaround for myself..
So it seems the crashing is happening when you call/do a transition to the same scene where you are at the moment so what I did is that:
1) I make a transition to my ResetScene which is just an empty scene - with some parameters so I could identify a previous scene
2) In ResetScene in DidMoveToView I make transition back to my previous scene
This is how I fixed this problem but I don't think it is an ideal solution. Note, you can't really spot a difference that there are 2 transitions instead of one.
Let's see if somebody would join this thread with more wisdom :)
Upvotes: 0