Flipping iPhone orientation reloads viewcontroller - ios

I have a viewcontroller with an SKview (I'm working with spritekit) inside of it and every time I change the orientation of the phone (from landscape one way to landscape another way or vise versa) it reloads the viewcontroller as if I had just opened the app (the viewcontroller is the initial one).
Is there a work around for it?
I can't seem to find anyone having the same problem.
Code:
http://pastie.org/8669630

You are setting up your SKView in viewWillLayoutSubview which gets called every time device is rotated (view frame changes).
Which is good, because view will have correct dimensions, but you should place some var to know should you set up the view again. For example BOOL sceneSetUp
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if(!self.sceneSetUp){
// Configure the view.
SKView * skView = (SKView *)self.view;
//skView.showsFPS = YES;
// Create and configure the scene.
SKScene * startScene = [StartViewController sceneWithSize:skView.bounds.size];
startScene.scaleMode = SKSceneScaleModeAspectFill;
SKScene * scene = [gameViewController sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:startScene];
//[skView presentScene:scene];
self.sceneSetUp = YES;
}
}

Related

Spritekit wont show presented scene

Im having a problem. When i present a new scene in spritekit (with objective c) It only shows a gray color with node and fps count on the screen.
I have animated the scene in the .sks file so it should not look like this.
The transition when im presenting the new scene also works, but it just wont show the images and background that i animated in the .sks file.
Here is the code on how i do it.
//In gameviewcontroller.m
// Creating and configuring the scene.
GameScene *Level1 = [GameScene nodeWithFileNamed:#"GameSceneLevel1"];
Level1.scaleMode = SKSceneScaleModeAspectFill;
// GameScene.m inside touchesbegan
SKTransition *reveal = [SKTransition doorwayWithDuration:4];
GameScene *Level1 = [GameScene sceneWithSize:self.view.bounds.size];
Level1.scaleMode = SKSceneScaleModeAspectFill;
[self.view presentScene:Level1 transition:reveal];
You have originally loaded scene from .sks file and as you said you have some animations there. Later on, (inside touchesBegan) you are creating a scene by providing a size (using sceneWithSize static method). So the scene is not loaded from from the archive.
To fix the problem, load your scene like you did initially, in the GameViewController.
EDIT:
To transition between two scenes you have to create two .sks files. You can name them like this : MenuScene and GameScene (you already have this one by default). Note that when you create these files you don't have to write an extension (.sks) but rather just file name. Then you have to create corresponding .m and .h files. So create MenuScene.m and MenuScene.h. GameScene .m and .h files are there by default.
MenuScene should be a subclass (not necessarily direct subclass) of an SKScene.
Then inside of your view controller:
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
GameScene *scene = [GameScene nodeWithFileNamed:#"GameScene"];
scene.scaleMode = SKSceneScaleModeAspectFill;
scene.size = skView.bounds.size;
[skView presentScene:scene];
}
Later on in your GameScene's touchesBegan method if you want to transition to the MenuScene, you should do something like this :
MenuScene *nextScene = [MenuScene nodeWithFileNamed:#"MenuScene"];
SKTransition *transition = [SKTransition fadeWithDuration:3];
[self.view presentScene:nextScene transition:transition];
Similarly, to transition back to the GameScene, in your MenuScene's touchesBegan, do this:
GameScene *nextScene = [GameScene nodeWithFileNamed:#"GameScene"];
SKTransition *transition = [SKTransition fadeWithDuration:3];
[self.view presentScene:nextScene transition:transition];
Of course right before each transition you can set scene's scale mode to match the scale mode of the old scene.
From your code, it looks like you are trying to make a transition to the same scene: GameScene -> GameScene. That is certainly possible, but are you sure you wanted that ?
If so, just use the code I've provided for MenuScene's touchesBegan method.

More Sprite Kit Game modes

I have a small game and I wish to present, in the menu, 2 game modes:
I have the first up and running from my original sprite kit scene and, in order to build my second one, I added another view to the storyboard, created another scene, linked them up just like the originals:
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = NO;
skView.showsNodeCount = NO;
skView.multipleTouchEnabled = YES;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
and linked it to another button in my menu. The problem was, whenever i would press the button to go to the second game mode I would get a SIGABRT Thread 1 error. I made sure everything I linked was declared and valid and still got the error. I then removed the second SKScene (MyScene) and the view was loaded with no problem... just no content.
Is there a specific way I must proceed in order to have another View linked to a SpriteKit game?

UIButton Hiding in Skscene Xcode

I am making an app that will switch to a different screen when it reaches a random number of clicks on the screen. I am using a button that is hidden to segue to the end screen. When I hide the button in the viewDidLoad, it will not appear when called in another method after it reaches the required number of randomized clicks Why does the hidden button not become visible?
-(void)viewDidLoad
{
[super viewDidLoad];
Final.hidden = YES;
SKView * skView = (SKView *)self.view;
skView.showsNodeCount = NO;
SKScene * scene = [BellPepperMyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
-(IBAction)GoToNewScreen:(id)sender {
Final.hidden = false;
}
-(void)goToEndScreen{
[self GoToNewScreen:nil];
}
Assuming Final is a UIButton, there are a few things you want to be aware of. First is that you should be setting Final.alpha = 0, and not Final.hidden = YES. This can cause problems with it receiving touch events.
You should also make sure that you have the order of the views setup right. If you want to makes sure that the button is visible you can call [self.view bringSubviewToFront:Final].

How to stop Sprite Kit from reinitializing the scene with iAd banner

I made a game using sprite kit in landscape mode. The only allowed orientations are landscape left and landscape right. When I select the banner ad in my game, rather than freezing the scene and returning to the original point in the game, the entire scene reinitializes itself (music player restarts, content shows as start screen, etc).
The same thing happens when I flip the phone around so that the orientation switches. How can I prevent this?
As for when you flip your phone you need this...
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
SKView * skView = (SKView *)self.view;
if ( !skView.scene ) {...
SKScene * scene = [MenuScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
[skView presentScene:scene];
}
}
I'm still looking into the iAd issue, I'll update if I figure anything out.
Thanks for the response. That was the problem. I had been initializing the scene in the viewWillLayoutSubviews method in my root view controller. I moved the scene initialization to the viewDidLoad method and it fixed the issue.

Positioning SKView / SKScene that has SKSceneScaleModeAspectFit?

I'm using a basic setup with a SKView to display a SKScene. The SKScene has a pre-defined size and uses a scale mode SKSceneScaleModeAspectFit:
- (void)viewDidLoad {
[super viewDidLoad];
SKView *skView = (SKView *)self.view;
SKScene *scene = [MyScene sceneWithSize:CGSizeMake(320, 480)];
scene.scaleMode = SKSceneScaleModeAspectFit;
[skView presentScene:scene];
}
As expected, on iPhone 5 this causes letterboxing, i.e. black sections above and under my scene. On iPad, letterboxing causes black stripes to the left and right of the scene.
However, I'd like to position the scene e.g. on iPhone 5 so that the scene is aligned to the bottom of the screen, while all of the black space is positioned above the scene. Is this possible?
I've tried quite a few things with .frame .center .origin, etc. properties of the SKView/SKScene, but can't seem to be able to move the 'display area'. For example, adding
[scene runAction:[SKAction moveTo:CGPointMake(0,-44) duration:0]];
moves the scene's contents inside the display area but not the area itself.
Any ideas?

Resources