2

My game app that was working perfectly fine on IOS 8 (built with Xcode 6) is all of sudden experiencing many issues when built using Xcode 7 with IOS 9. Here is how the game used to look. (How it should look). Level Select PageGame Scene Here is it running on IOS 9 (broken) Level Select Page BrokenGame Scene Broken

GAME SCENE CODE

Code for creating the Game Board in Game Scene

-(void) createBoard {



self.buttons=[NSMutableArray new];

if (self.boardBlur != nil ) {
    [self.boardBlur removeAllChildren];
}

self.backgroundColor=[UIColor clearColor];

// Use for Christmas Easter egg

/*  NSString *snowPath = [[NSBundle mainBundle] pathForResource:@"SnowParticle" ofType:@"sks"];
 SKEmitterNode *snow = [NSKeyedUnarchiver unarchiveObjectWithFile:snowPath];
 snow.particlePositionRange=CGVectorMake(self.frame.size.width, 20);

 snow.position=CGPointMake(self.frame.size.width/2,self.frame.size.height);

 snow.zPosition=-3;

 [self addChild:snow];*/

if (self.boardFrame != nil) {
    [self.boardFrame removeFromParent];
    [self.boundingBox removeFromParent];
}

self.boardFrame = [SKSpriteNode spriteNodeWithImageNamed:@"gameBoard2"];
self.boardFrame.color= self.level.baseColor;
self.boardFrame.colorBlendFactor=1.0;
self.boardFrame.alpha = .7;
self.boardFrame.zPosition=-1;
  //  self.boardFrame.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)+40);

self.boardFrame.size=self.size;

if (self.boardBlur == nil) {
self.boardBlur=[[SKEffectNode alloc]init];
     self.boardBlur.filter=[CIFilter filterWithName:@"CIGaussianBlur"];
    [self.boardBlur.filter setDefaults];
    [self.boardBlur.filter setValue:@5.0 forKey:kCIInputRadiusKey];
     self.boardBlur.shouldEnableEffects=NO;
     self.boardBlur.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)+40);
    [self addChild:self.boardBlur];
}

[self.boardBlur addChild:self.boardFrame];


 [self displayMessage:self.level.name color:[UIColor whiteColor]];

[self createHUD];

CGRect playSurface=CGRectInset(self.frame, 36,36);

self.gridSize=fmin(playSurface.size.width,playSurface.size.height)/(fmax(self.level.width,self.level.height));

if (self.gridSize > 60) {
    self.gridSize=60;
}

CGRect oldPlaySurface =playSurface;

playSurface=CGRectMake(0,0,self.gridSize*self.level.width,self.gridSize*self.level.height);

self.boardFrame.size=CGRectInset(playSurface, -24, -24).size;
self.boardBlur.zPosition=-2;

self.boundingBox=[SKShapeNode shapeNodeWithRect:CGRectInset(self.boardFrame.frame,self.gridSize/1.7,self.gridSize/1.7) cornerRadius:7.0];
self.boundingBox.strokeColor=[SKColor clearColor];

self.boundingBox.position=self.boardBlur.position;
self.boundingBox.zPosition=-5;
[self addChild:self.boundingBox];

self.ballSize=self.gridSize-6;
self.enlargeAction=[SKAction resizeToWidth:self.ballSize+5 height:self.ballSize+5 duration:0.2];
self.shrinkAction=[SKAction resizeToWidth:self.ballSize height:self.ballSize duration:0.2];

self.enlargeInAction=[SKAction resizeToWidth:self.ballSize height:self.ballSize duration:0.3];
self.shrinkOutAction=[SKAction resizeToWidth:0 height:0 duration:0.3];


CGFloat horizontalSpace = (playSurface.size.width-self.gridSize*self.level.width);
CGFloat verticalSpace = (playSurface.size.height-self.gridSize*self.level.height);

self.topOffset=80+verticalSpace/2+(oldPlaySurface.size.height-playSurface.size.height)/2;

self.leftOffset=40+horizontalSpace/2+(oldPlaySurface.size.width-playSurface.size.width)/2;

for (int y=0; y < self.level.height; y++) {
    for (int x = 0; x < self.level.width; x++) {
      //SKSpriteNode *backgroundButtonNode = [SKSpriteNode spriteNodeWithTexture:dotTexture];
        SKShapeNode *backgroundButtonNode=[SKShapeNode shapeNodeWithCircleOfRadius:0.5];
   //     backgroundButtonNode.size=ballSize;
        backgroundButtonNode.userInteractionEnabled=NO;
        backgroundButtonNode.zPosition=0;
        backgroundButtonNode.fillColor=[UIColor whiteColor];
    //    backgroundButtonNode.colorBlendFactor=1.0;

        backgroundButtonNode.position=[self.boardFrame convertPoint:CGPointMake(self.leftOffset+(self.gridSize*x)+self.ballSize/2,self.topOffset+(self.gridSize*y)+self.ballSize/2) fromNode:self];

        [self.boardFrame addChild: backgroundButtonNode];
    }
}


CGFloat menuiconsize=fmin(self.ballSize, 60.0);

CGFloat menuWidth=fmin(self.boardFrame.size.width-40,420);

if (self.menuBar != nil) {
    [self.menuBar removeFromParent];
}

self.menuBar=[[MenuBar alloc]initWithSize:CGSizeMake(menuWidth,self.ballSize+12) iconSize:CGSizeMake(menuiconsize,menuiconsize) Level:self.level];
self.menuBar.delegate=self;
[self addChild:self.menuBar];

self.menuBar.position=CGPointMake(self.frame.size.width/2-(menuWidth)/2, self.topOffset-menuiconsize-40);

self.menuBar.userInteractionEnabled=YES;
self.gameOver=NO;

}

Code for the HUD (Stars, Goal...)

-(void) createHUD {
if (self.topHud == nil) {
    self.topHud=[SKShapeNode shapeNodeWithRect:CGRectMake(-2,self.frame.size.height-62,self.frame.size.width+2,64)];

    self.topHud.fillColor=[UIColor clearColor];
    self.topHud.strokeColor=[UIColor clearColor];
    self.topHud.lineWidth=0;
    [self addChild:self.topHud];

    UIColor *textColor=[self.level textColor];

    self.scoreLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.scoreLabel.fontSize=20;
    self.scoreLabel.alpha = 1;
    self.scoreLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeRight;
    self.scoreLabel.fontColor=textColor;
    self.scoreLabel.position=CGPointMake(self.frame.size.width-8,self.frame.size.height-25);
    self.score=0;
    [self.topHud addChild:self.scoreLabel];

    self.highScoreLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.highScoreLabel.fontSize=20;
    self.highScoreLabel.alpha = 1;
    self.highScoreLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeRight;
    self.highScoreLabel.fontColor=textColor;
    self.highScoreLabel.position=CGPointMake(self.frame.size.width-8,self.frame.size.height-50);
    //self.highScore=0;
    [self.topHud addChild:self.highScoreLabel];
    [self updateScore];

    self.doughLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.doughLabel.fontColor=textColor;
    self.doughLabel.fontSize=20;
    self.doughLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeCenter;
    self.doughLabel.position=CGPointMake(self.frame.size.width/2, 20);
    [self coinBalanceChanged:nil];
    [self addChild:self.doughLabel];

    self.progressNode=[SKCropNode new];
    self.progressNode.zPosition=1;
    SKNode *dimStarsNode=[SKNode new];
    SKSpriteNode *maskNode=[SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:CGSizeMake(66,24)];
    maskNode.position=CGPointMake(-42, 0);
    //  self.progressNode.maskNode=maskNode;
    for (int i=0;i<3;i++) {
        SKSpriteNode *starNode=[SKSpriteNode spriteNodeWithImageNamed:@"SugarCookie"];
        starNode.size=CGSizeMake(20,20);
        starNode.position=CGPointMake(i*22,0);
        [self.progressNode addChild:starNode];
        starNode=[SKSpriteNode spriteNodeWithImageNamed:@"SugarCookie"];
        starNode.size=CGSizeMake(20,20);
        starNode.zPosition=1;
        starNode.alpha=0.3;
        starNode.position=CGPointMake(i*22,0);
        [dimStarsNode addChild:starNode];
    }

    self.progressNode.maskNode= maskNode;

    //  self.progressNode.maskNode=maskNode;
    self.progressNode.position=CGPointMake(22, self.frame.size.height-18);
    dimStarsNode.position=CGPointMake(22, self.frame.size.height-18);

    dimStarsNode.zPosition=0;

    [self addChild:dimStarsNode];
    [self addChild:self.progressNode];

    self.goalLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.goalLabel.fontSize=20;
    self.goalLabel.alpha = 1;
    self.goalLabel.fontColor=textColor;
    self.goalLabel.position=CGPointMake(12,self.frame.size.height-50);
    self.goalLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeLeft;
    self.goalLabel.text=[NSString stringWithFormat:@"Goal: %ld",(long)self.level.targetScore];
    [self addChild:self.goalLabel];

    self.storeButton=[[GameButtonNode alloc]initWithColor:self.level.baseColor strokeColor:[self.level levelColorWithBrightnessDelta:0.3 alpha:1.0] imageName:@"store" radius:25 physics:NO delegate:self];

    self.storeButton.position=CGPointMake(self.frame.size.width-40,35);
    [self addChild:self.storeButton];

     self.menuButton=[[GameButtonNode alloc]initWithColor:self.level.baseColor strokeColor:[self.level levelColorWithBrightnessDelta:0.3 alpha:1.0] imageName:@"menuButton" radius:25 physics:NO delegate:self];

    self.bottomMenuNode=[SKShapeNode shapeNodeWithRect:CGRectMake(5, 30, 180, 60) cornerRadius:7.0];
    self.bottomMenuNode.strokeColor=[UIColor clearColor];
    self.bottomMenuNode.fillColor=[self.level levelColorWithBrightnessDelta:-0.6 alpha:0.2];
    self.bottomMenuNode.zPosition=6;

    self.homeButton=[[GameButtonNode alloc]initWithColor:self.level.baseColor strokeColor:[self.level levelColorWithBrightnessDelta:0.3 alpha:1.0] imageName:@"homeButton" radius:25 physics:NO delegate:self];
    self.homeButton.position=CGPointMake(35,60);
    [self.bottomMenuNode addChild:self.homeButton];

    self.menuReplayButton=[[GameButtonNode alloc]initWithColor:self.level.baseColor strokeColor:[self.level levelColorWithBrightnessDelta:0.3 alpha:1.0] imageName:@"replayButton" radius:25 physics:NO delegate:self];
    self.menuReplayButton.position=CGPointMake(95,60);
    [self.bottomMenuNode addChild:self.menuReplayButton];

    NSString *soundImage=[self soundImage];

    self.soundButton=[[GameButtonNode alloc]initWithColor:self.level.baseColor strokeColor:[self.level levelColorWithBrightnessDelta:0.3 alpha:1.0] imageName:soundImage radius:25 physics:NO delegate:self];
    self.soundButton.position=CGPointMake(155,60);


    [self.bottomMenuNode addChild:self.soundButton];
    self.bottomMenuNode.position=CGPointMake(0, 0);
    self.bottomMenuNode.hidden=YES;
    self.bottomMenuNode.xScale=0.1;
    self.bottomMenuNode.yScale=0.1;

    [self.menuButton addChild:self.bottomMenuNode];


    self.menuButton.position=CGPointMake(40,35);
    self.menuButton.zPosition=7;
    [self addChild:self.menuButton];
}

}

Code for GameBoardNode

-(instancetype) initWithColor:(UIColor *)color strokeColor:(UIColor *) strokeColor imageName:(NSString *)imageName radius:(CGFloat)radius physics:(BOOL)physics delegate:(id<GameButtonNodeDelegate>)delegate {

if (self=[super init]) {
    self.strokeColor=strokeColor;
    self.ball=[SKShapeNode shapeNodeWithCircleOfRadius:radius];
    self.ball.fillColor=color;
    self.ball.strokeColor=strokeColor;
    self.ball.lineWidth=3.0;
    self.ball.zPosition=0;

    self.touchDelegate=delegate;

    [self addChild:self.ball];

    self.icon=[SKSpriteNode spriteNodeWithImageNamed:imageName];
    self.icon.size=CGSizeMake(30, 30);
    self.icon.zPosition=0;
    self.enabled=YES;


    [self addChild:self.icon];

    if (physics) {

    self.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:radius ];
    self.physicsBody.affectedByGravity=YES;

    }

    self.userInteractionEnabled=YES;

    self.fadeIn=[SKAction fadeInWithDuration:0.3];
    self.fadeOutRemove=[SKAction sequence:@[[SKAction waitForDuration:0.2],[SKAction fadeOutWithDuration:0.3],[SKAction removeFromParent]]];

}

return self;

}

LEVEL SELECT

The only issue with this view is the background image (blue gradient) appears and then fades away. The background image is set up in the storyboard.

  • Most Images are coming from Images.xcassets folder.
  • All images are png.
  • Bitcode is off (if that makes a difference)

Any other code or images, just ask.

How can I fix this problem and get my game working properly again?

huddie96
  • 1,240
  • 2
  • 13
  • 26
  • 1
    I've been experiencing similar problems in regards to images with IOS 9, which I have reported to Apple, but have not received a response yet. By chance, do the images not appear only on iPhone 4s and iPhone 5 devices and simulator? Also, are your images @2x~iphone, because I found changing the images to @2x universal seems to make them appear again. – Jarron Oct 15 '15 at 15:52
  • They don't work on iPhone 5s. I will check the other 2 suggestions. – huddie96 Oct 15 '15 at 19:01
  • @Jarron The game is universal (iPad , iPhone) so it uses universal Images. – huddie96 Oct 15 '15 at 19:10
  • Hmmm, I've only experienced problems with the @2x~iphone myself. The only other thing that may work (worked for me), is loading the images from an atlas, rather then the images.xcassets folder. It's a bit annoying doing this, but it's the only other suggestion I have. – Jarron Oct 16 '15 at 02:38
  • @huddie96 I have my own share of issues for the scene files - you may like to look at my question over here: http://stackoverflow.com/q/33068342/1396265 - maybe it is related to the things you encountered. – Rainer Schwarze Oct 17 '15 at 19:26
  • @RainerSchwarze theres no answer on yours either – huddie96 Oct 18 '15 at 06:14
  • Does this answer help: http://stackoverflow.com/questions/32665866/ios9-sprite-kit-issues/32675553#32675553? Set `zPosition` for your background node and every other sprite. – WangYudong Oct 18 '15 at 12:35
  • @WangYudong Every zPosition is set – huddie96 Oct 18 '15 at 12:41

1 Answers1

2

iOS 9 cares more about zPosition than iOS 8 did. In the past if you didn't set the zPosition iOS8 would do a really good job of assuming what you wanted. In iOS9 it doesn't care and will render it however it wants.

I have also noticed leaving it at zero is also very bad. For instance if you have a node at 0 and add a child with a zPosition of 0...they both are 0 and iOS9 will pick which it should render first. If I am correct this should get your top hud showing back up again.

if (self.topHud == nil) {
    self.topHud=[SKShapeNode shapeNodeWithRect:CGRectMake(-2,self.frame.size.height-62,self.frame.size.width+2,64)];

    self.topHud.fillColor=[UIColor clearColor];
    self.topHud.strokeColor=[UIColor clearColor];
    self.topHud.lineWidth=0;
    self.topHud.zPosition = 100;//added zPosition
    [self addChild:self.topHud];

    UIColor *textColor=[self.level textColor];

    self.scoreLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.scoreLabel.fontSize=20;
    self.scoreLabel.alpha = 1;
    self.scoreLabel.zPosition = 1;//added zPosition
    self.scoreLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeRight;
    self.scoreLabel.fontColor=textColor;
    self.scoreLabel.position=CGPointMake(self.frame.size.width-8,self.frame.size.height-25);
    self.score=0;
    [self.topHud addChild:self.scoreLabel];

    self.highScoreLabel=[SKLabelNode labelNodeWithFontNamed:@"Blow"];
    self.highScoreLabel.fontSize=20;
    self.highScoreLabel.alpha = 1;
    self.highScoreLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentModeRight;
    self.highScoreLabel.fontColor=textColor;
    self.highScoreLabel.position=CGPointMake(self.frame.size.width-8,self.frame.size.height-50);
    self.highScoreLabel.zPosition = 1;//added zPosition
    //self.highScore=0;
    [self.topHud addChild:self.highScoreLabel];

Note 4 zPositions added. I hope that helps get things going in the right direction.

Skyler Lauren
  • 3,792
  • 3
  • 18
  • 30
  • zPositions do seem to be the problem the higher the number the earlier they are created? For instance if I had a view with zPos 1 and another with zPos 2 same spot and size, I would never see the first view? – huddie96 Oct 20 '15 at 18:42
  • 1
    The lower the number the earlier it is drawn. For example background would be 0, game stuff could be 1 to 99 and hud could be 100 and that would render in the right order. Also note that zPosition is based on parent zPosition. So if one is zPosition 10 and you add a child with zPosition 2...its actual world zPosition would be 12. Hopefully that makes sense. – Skyler Lauren Oct 20 '15 at 18:54
  • your answer on the cause was correct but sample code didn't work – huddie96 Oct 20 '15 at 18:54
  • @huddie96 yeah I accidentally miss typed and put topHud zPosition to 1 instead of score label. Making the hud to low again =/... Edited answer and that should fix it. – Skyler Lauren Oct 20 '15 at 18:57
  • why is scoreLabel getting 2 zPos ? – huddie96 Oct 20 '15 at 19:00
  • @huddie96 because I am trying to type a small text editor window (ie it is an accident). Does that work correctly for you now? – Skyler Lauren Oct 20 '15 at 19:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92893/discussion-between-skyler-lauren-and-huddie96). – Skyler Lauren Oct 20 '15 at 19:04
  • I apologize I've been trying to get this working forever – huddie96 Oct 20 '15 at 19:04