Presenting a scene in SpriteKit without discarding the previous? - ios

My situation is that I have a GameMenuScene and after the user chooses a level, I want to present the LevelScene. But I do not want to have the previous GameMenuScene discarded because the LevelScene is actually a #property of GameMenuScene and whether or not the user completes the level is to be saved as a #property of LevelScene, which the GameMenuScene should be able to access after the user finishes or exits the level. If I simply use presentScene:transition, the GameMenuScene is discarded and the information cannot pass back.
My question: Is there a way to stack or push the scenes on top of each other without discarding the previous (preferably using a transition animation)? I could not find a method for this specific purpose in the Apple Documentation for SKScene.
Note: Another StackOverflow answer to a similar question suggests to create a new UIViewController, present the LevelScene in there and then present the UIViewController modally. But I was hoping there was an existing method in the Apple Documentation that I have missed to present the scene itself scene modally without having to create UIVIewControllers.

There is no navigation controller-like capability for SKScenes that allows you to push and pop scenes. You will need to write code to manage and present your scenes.
Here's a simple view controller implementation that allows you to switch between two scenes (by swiping) without discarding the other scene.
#interface ViewController()
#property BOOL viewFlag;
#property SKScene *scene1;
#property SKScene *scene2;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeGesture];
// Create and configure scene 1.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
self.scene1 = scene;
// Present the scene 1.
[skView presentScene:scene];
// Create and configure scene 2.
scene = [MySecondScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
self.scene2 = scene;
}
- (void) handleSwipeGesture:(id)sender
{
SKView * skView = (SKView *)self.view;
_viewFlag = !_viewFlag;
if (_viewFlag) {
[skView presentScene:_scene1];
}
else {
[skView presentScene:_scene2];
}
}
#end

Related

Present scene from file in Sprite Kit

I have level1 presented from GameViewController using unarchiveFromFile. But how can I present level2 from sks file?
I mean only present level2 and use it with level1 code, because here I have all game logic.
EDIT:
I present my scene from sks file like this:
GameViewController.m
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = YES;
// Create and configure the scene.
GameScene *scene = [GameScene unarchiveFromFile:#"GameScene"];
scene.scaleMode = SKSceneScaleModeResizeFill;
// Present the scene.
[skView presentScene:scene];
And I would like to present another scene from another SKS file from GameScene.m file. And I can't call unarchieveFromFile from GameScene.m
Just make sure that you are casting it as the object that you want to be using
GameScene.unarchiveFromFile("Level1") as? GameScene;
GameScene.unarchiveFromFile("Level2") as? GameScene;
Where GameScene is the swift class that you want to be using for your logic

Using Navigation controller for a start screen ios

I've come to the point where I need to make a start screen for my game made with sprite kit. I can not get it to show with any of the code and tutorials I have read and watched.
I want to use a navigation controller/view controller to begin at the start screen and have it linked to my app but I am not sure how to link my game's code to the view controller.
Using a navigation controller, how would I drag it into my game's code as a #IBAction declaration? Thank you.
Edit with current code:
ViewController.m:
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
scene.viewController = self;
[skView presentScene:scene];
}
MyScene.h:
#interface MyScene : SKScene <SKPhysicsContactDelegate>
#property (strong, nonatomic) UIViewController *viewController;
#end
This answer is based on the one here, but has been translated to Objective-C.
The problem that you are facing is that an SKScene does not have direct access to it's viewController, but just the view in which it is contained. You need to create a pointer to it manually. This can be done by creating a property for the SKScene:
#interface GameScene : SKScene
#property (strong, nonatomic) UIViewController *viewController;
#end
Then, in the viewController class, just before [skView presentScene:scene];
scene.viewController = self;
Now, you can access the viewController directly. Simply call the segue on this viewController:
-(void)goToHomeScreen {
[self.viewController.navigationController popToRootViewControllerAnimated:YES];
}
You can perform other navigationController operations in a similar way.

Transition from ViewController to SKScene

I'm currently making a game in which the main game is a SKScene however the menu is a UIViewController. I have a button which when tapped should transition from the menu to the SKScene. What code should i write in the IBAction?
I'm running xcode6 beta 5. If that changes anything.
Simply load view controller from the storyboard. And after it present it.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
MyViewController *lcvc = (MyViewController*)[storyboard instantiateViewControllerWithIdentifier:#"MyViewController"];
lcvc.modalPresentationStyle= UIModalPresentationCustom;
[self presentViewController:lcvc animated:YES completion:nil];
If you have only one view controller that contains a button and will later present the SKScene, you can implement an IBAction similar to the following:
Objective C
- (IBAction) buttonPressed:(UIButton *)button
{
// Remove button from the view
[button removeFromSuperview];
// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;
// Create and configure the scene.
SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
}
Swift
#IBAction func buttonPressed(button:UIButton)
{
// Remove button from the view
button.removeFromSuperview()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
If you have two view controllers, one containing the button and the other that will present your SKScene, then you don't need an IBAction. You can simply create a segue from the button to your game view controller. From the storyboard, right-click (or control-click) on the button and drag from the Triggered Segues's action to the game view controller and release the mouse/trackpad button.

How can i switch from SKScene to UIView

I'm using Sprite kit framework to create a game.
My first scene is MyScene.My Scene is a menu, but i want when is clicked on start to switch to the first view from the story board.
This is the way i switch to another SKScene
Scene001 *start = [[Scene001 alloc] initWithSize:self.size];
SKTransition *reveal = [SKTransition fadeWithColor:[UIColor clearColor] duration:0.5];
[self.scene.view presentScene: start transition: reveal];
Now the question is how to switch to the storyboard scene and vice versa.
I know this is old but just incase someone comes across it and needs an answer:
What I did in my game was make my GameViewController be a delegate of the SKScene. When the user is finished in the SKScene, I called my delegate function in the GameViewController which simply does a performSegueWithIdentifier.
Your viewController that creates your scene has can run segue's. So you need a way to get back to it from your SKScene. Simply make your SKScene a delegate and when your viewController creates it, set the delegate. Then when you want to switch, call the delegate function.
This is my GameViewController that creates my scene:
- (void)viewWillAppear:(BOOL)animated {
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
MyScene *scene = [MyScene sceneWithSize:self.view.bounds.size];
scene.delegate = self;
[skView presentScene:scene];
}
}
// A delegate function
- (void)onExitGame {
[self performSegueWithIdentifier:#"GoToNextScene" sender:self];
}
Then from my MyScene when you're ready to switch the storyboard call the delegate function:
if (self.delegate) {
self.delegate.onExitGame();
}

Showing iAds in SpriteKit Game

I get the following error when I try to ad iAds to my SpriteKit game. Anyone know why this is?
-[UIView scene]: unrecognized selector sent to instance 0x10da31fb0
ViewController.m
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
// Configure the view.
SKView * skView = (SKView *)self.view;
if (!skView.scene) {
skView.showsFPS = NO;
skView.showsNodeCount = NO;
// Create and configure the scene.
SKScene * scene = [HomeScreen sceneWithSize:skView.bounds.size];
scene.scaleMode = SKSceneScaleModeAspectFill;
// Present the scene.
[skView presentScene:scene];
self.canDisplayBannerAds = YES;
}
}
In addition to my comment (regarding iAD) the error shows me that somehow to view's class is not correct. It should be SKView.
To correct this go to Interface Builder and for that particular view change the class using the Identity inspector (3rd "tab") to SKView.
It happened to me when manually created from the scratch a SpriteKit project.
Hope it helps! :)

Resources