So this loop runs in the skscene. It works perfectly in my multiplayer game, however.. In the single player mode it isn't working quite so well..
The problem is, it's meant to iterate through the loop performing fast animations. However, the whole thing just freezes and animates at the end of the loop.
for (int i = 0; i < 7; i++) {
//to loop between players
for (int j = 0; j < 4; j++) {
NSString *imageName = [NSString stringWithFormat:@"back"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
cardDisplay = [CardSpriteNode spriteNodeWithTexture:texture];
cardDisplay.size = CGSizeMake(104, 144);
cardDisplay.position = _dealPosition;
cardDisplay.zPosition = zPosCount;
zPosCount++;
cardDisplay.userInteractionEnabled = YES;
cardDisplay.name = @"cardBack";
[self addChild:cardDisplay];
CGPoint moveToPosition;
//change position to deal to
if (j == 0) {
moveToPosition = position1;
}
else if (j == 1) {
moveToPosition = position2;
}
else if (j == 2) {
moveToPosition = position3;
}
else if (j == 3) {
moveToPosition = position4;
}
[cardDisplay runAction:[SKAction moveTo:moveToPosition duration:0.3]];
[cardDisplay runAction:[SKAction fadeOutWithDuration:0.4]];
[NSThread sleepForTimeInterval:0.1];
if (i == 6 && j == 4 - 1) {
SKNode *node = [self childNodeWithName:@"cardBack"];
[node removeAllChildren];
for (int p = 0; p < [playerCards count]; p++) {
addBegin = p * (cardDisplay.size.width / 3.0);
NSString *imageName = [NSString stringWithFormat:@"%@", playerCards[p]];
NSString *bundle = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
cardDisplay = [CardSpriteNode spriteNodeWithTexture:texture];
cardDisplay.size = CGSizeMake(104, 144);
cardDisplay.anchorPoint = CGPointMake(0.5, 0.5);
cardDisplay.position = CGPointMake(-self.frame.size.width/2.8 + addBegin, -300);
cardDisplay.zPosition = 1;
cardDisplay.userInteractionEnabled = NO;
cardDisplay.name = [NSString stringWithFormat:@"%@", playerCards[p]];
[self addChild:cardDisplay];
CGPoint moveToNewPosition = CGPointMake(-self.frame.size.width/2.8 + addBegin, -218);
[cardDisplay runAction:[SKAction moveTo:moveToNewPosition duration:1]];
[NSThread sleepForTimeInterval:0.2];
}
}
}
}
Now like I say, this works fine in my other skscene, but in this one it doesn't and as far as I can see everything is initialised.
From Apple's documentation:
Grand Central Dispatch (GCD) comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware in iOS and OS X.
To use GCD is quite simple. Here's an example of your code being executed on a separate thread using GCD.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 7; i++) {
//to loop between players
for (int j = 0; j < 4; j++) {
NSString *imageName = [NSString stringWithFormat:@"back"];
NSString *bundle = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
cardDisplay = [CardSpriteNode spriteNodeWithTexture:texture];
cardDisplay.size = CGSizeMake(104, 144);
cardDisplay.position = _dealPosition;
cardDisplay.zPosition = zPosCount;
zPosCount++;
cardDisplay.userInteractionEnabled = YES;
cardDisplay.name = @"cardBack";
dispatch_async(dispatch_get_main_queue(), ^(void){
[self addChild:cardDisplay];
});
CGPoint moveToPosition;
//change position to deal to
if (j == 0) {
moveToPosition = position1;
}
else if (j == 1) {
moveToPosition = position2;
}
else if (j == 2) {
moveToPosition = position3;
}
else if (j == 3) {
moveToPosition = position4;
}
[cardDisplay runAction:[SKAction moveTo:moveToPosition duration:0.3]];
[cardDisplay runAction:[SKAction fadeOutWithDuration:0.4]];
[NSThread sleepForTimeInterval:0.1];
if (i == 6 && j == 4 - 1) {
SKNode *node = [self childNodeWithName:@"cardBack"];
[node removeAllChildren];
for (int p = 0; p < [playerCards count]; p++) {
addBegin = p * (cardDisplay.size.width / 3.0);
NSString *imageName = [NSString stringWithFormat:@"%@", playerCards[p]];
NSString *bundle = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
cardDisplay = [CardSpriteNode spriteNodeWithTexture:texture];
cardDisplay.size = CGSizeMake(104, 144);
cardDisplay.anchorPoint = CGPointMake(0.5, 0.5);
cardDisplay.position = CGPointMake(-self.frame.size.width/2.8 + addBegin, -300);
cardDisplay.zPosition = 1;
cardDisplay.userInteractionEnabled = NO;
cardDisplay.name = [NSString stringWithFormat:@"%@", playerCards[p]];
dispatch_async(dispatch_get_main_queue(), ^(void){
[self addChild:cardDisplay];
});
CGPoint moveToNewPosition = CGPointMake(-self.frame.size.width/2.8 + addBegin, -218);
[cardDisplay runAction:[SKAction moveTo:moveToNewPosition duration:1]];
[NSThread sleepForTimeInterval:0.2];
}
}
}
}
});
You'll notice in some places I used:
dispatch_async(dispatch_get_main_queue(), ^(void){
[self addChild:cardDisplay];
});
This will always contain code that will affect the UI; all UI code must be executed on the main thread.