How to choose which scene shows up first spritekit/swift? - swift

Where is it declared which scene will show up first on load up of the app? The first file I made which is the game obviously shows up first, but if I'm wanting to switch it so that my main menu pops up first, how and where do I do that?
Thanks

In the view controller, the first scene is set. By default, it's automatically set to GameScene but you can change this by altering the code in the GameScene. You should change this line in unarchive from file:
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameScene to
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! sceneName
and this line in didMoveToView
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
to
if let scene = GameScene.unarchiveFromFile("GameScene") as? sceneName {
This will cause the game to load sceneName, or whatever you scene is called as the initial scene.

Related

How do I load a sprite from .sks file to display in my ARSKView?

I have an ARKit app that uses SpriteKit to display SKNodes that correspond to ARAnchors in the AR session. I am using the ARSKViewDelegate method
func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode?
to display the nodes. This works for nodes I create and return in that method, but I have some more complicated nodes that I would like to design in an .sks file and then display for some anchors. When I return a node instantiated from an .sks file in that method the app crashes with an error saying the node is already in the scene (if the node is in the .sks file for the current scene), or already has a parent (if it is in an .sks file for a different scene).
How can I display sprites in ARKit that are drawn in an .sks file?
Try this approach:
if let view = self.view as! SKView? {
if let scene = SKScene(fileNamed: "mySpriteKitScene") {
guard let clone = scene.childNode(withName: "myRedSprite")?
.copy() as? SKSpriteNode
else { return }
clone.name = "mySecondRedSprite"
clone.position.x += 250
clone.physicsBody = SKPhysicsBody()
scene.addChild(clone)
view.presentScene(scene)
}
}

Swift Find Scene By Name

How do i make a Swift sprite kit game jump to another scene by searching for the scene with a string. so:
let scenename : String = "Map1"
let scene : SKSCene = SkScene.getscene(scenename)
Do we have something like that?
if not please help me with alternatives!
Thanks for your help and time!
Make a delegate call to your SKView from current scene, which is presenting the scene then present another scene like this:
let newScene = SKScene.init(fileNamed: "MyScene")
newScene!.scaleMode = SKSceneScaleMode.Fil
let reaveal = SKTransition.crossFadeWithDuration(0.01)
let aSKView = self.view as! SKView
aSKView.presentScene(newScene!, transition: reaveal)
Do check for memory leaks ;)

Swift, spritekit: How to restart GameScene after game over? Stop lagging?

Alright, so I have a sprite kit game in Swift here and I'm having trouble restarting my GameScene after it's game over.
Right now, when the user loses all their lives, a variable gameIsOver is set to true, which pauses specific nodes within the scene as well as sets off a timer. After this timer ends, I move to my Game Over scene. From the Game Over scene, the user can either go back to home or restart the game.
Here is how I transition to my game over scene:
countdown(circle, steps: 120, duration: 5) {
//Performed when timer ends
self.gameSoundTrack.stop()
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("GOViewController")
self.viewController!.presentViewController(vc, animated: true, completion: nil)
//Resetting GameScene
self.removeAllChildren()
self.removeAllActions()
self.scene?.removeFromParent()
self.paused = true
gameIsOver = false
}
I pause my scene here is because, if I don't, when GameScene is reloaded gameIsOver is still set to true and my app crashes. I don't know why this occurs considering I set gameIsOver to false here.
After moving from GameScene to my game over scene and back to GameScene, or from GameScene to my home view controller and back to GameScene a couple times, my fps count has decreased so much that the whole game is lagging to the point where gameplay is impossible.
This leads me to believe that I am not removing/disposing of GameScene properly each time I present my game over scene.
I believe I'm having the same problem as here: In Swift on "game over" move from scene to another UIView and dispose the scene? , but I'm new to this and I can't figure out how they solved their problem.
How I can I completely reset/delete GameScene each time I present my Game Over scene in order to stop the lagging?
Your gameIsOver Bool will not keep a value while switching between scenes unless your make it a struct. So instead of
var gameIsOver = false
it should be
struct game {
static var IsOver : Bool = false
}
so when you change the value as things happen you call
game.IsOver = true
//if your calling it in a different View controller or scene than where you created it just put the name before it like so
GameViewController.game.IsOver = true
As for the transition back to your GameScene create a function
func goToGameScene(){
let gameScene:GameScene = GameScene(size: self.view!.bounds.size) // create your new scene
let transition = SKTransition.fadeWithDuration(1.0) // create type of transition (you can check in documentation for more transtions)
gameScene.scaleMode = SKSceneScaleMode.Fill
self.view!.presentScene(gameScene, transition: transition)
}
then whenever you want to reset to GameScene just call
goToGameScene()

Scene created in Sprite kit level editor is not working

I'm trying to do this for a while. I have a main scene for a game named PlayScene. I have a pause button there. When player is tapping that button I want to load another scene, named PauseScene. For visualy creating that scene I use Sprite kit level editor. So I have two files PauseScene.swiftand PauseScene.sks. But .sks content ( just a background for now) isn't unarchiving. I don't really know where could I make a mistake.
So this is my transition via pause button, located in PlayScene
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if self.nodeAtPoint(location) == self.pause {
var scene = PauseScene(size: self.size)
scene.paused = true
let skView = self.view as SKView!
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
scene.size = skView.bounds.size
skView.presentScene(scene)
}
}
And this is what I have in PauseScene.swift:
class PauseScene: SKScene {
override func didMoveToView(view: SKView) {
self.initPauseScene()
}
func initPauseScene() {
}
}
I tried this and it's not working very well. However that tutorial is closest I could get with my problem. It's not crushing and isn't showing any errors, but when I tap pause button it's transitioning to that scene without my background, just standard grey scene. This answer is not working for me. First suggestion show errors and when I tried second and tap the pause – game is crushing.
I don't know, that level editor is made for easier work but for know it just doubles it for me. I even thought that problem is in my background image maybe. But its standard .png. Why my content isn't showing up?
So I tried to copy GameViewController default code for loading GameScene and ended up with crashing. It's not the first time I have that error while trying to unarchive this. What does it mean? I got this when i tried to replace var scene = PauseScene(size: self.size) with a if let scene = PauseScene.unarchiveFromFile("PauseScene") as? PauseScene
It may be transition to a grey scene due to spelling errors or the file not even being in the mainBundle. I have tested this and it works. You need to make sure that you are writing the exact name of the .sks file when loading or else you get a grey screen.
Example
If the file is called GameScreen.sks and the class is called GameScene then if you put the class name when loading the .sks file you will get a grey screen.
let doors = SKTransition.doorwayWithDuration(1.0)
let archeryScene = GameScene(fileNamed: "GameScreen")
self.view?.presentScene(archeryScene, transition: doors)
So if we look at the second line of code, We see that it is loading the .sks file with the name GameScreen opposed to the class name GameScene. We also abort using the file extension because the compiler know by default it is a .sks file we are searching for in the mainBundle.
If you do keep getting a grey screen, Then it may be an error in spelling or ing you GameViewController, In the SKNode Extension, Be sure to change
extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)
archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
archiver.finishDecoding()
return scene
} else {
return nil
}
}
}
to this..
extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)
archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKScene
archiver.finishDecoding()
return scene
} else {
return nil
}
}
}
We just edited this line of code,
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
to this
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKScene
This will allow us to load multiple .sks files without any errors or crashes.

Swift multiple scenes

I have made a swift SpriteKit game but now I want to add a menu scene(and eventually a lose scene). So what I did was
I created a new scene called Menu scene.
I edited GameViewController and changed it to load menu scene(it worked).
In MenuScene.swift I put some code in so when a sprite was clicked it would run this code:
let reveal = SKTransition.flipHorizontalWithDuration(0.5)
let scene = GameScene(size: size)
self.view?.presentScene(scene, transition:reveal)
But when I click the button it flips round to the next scene and immediately crashes.
So my question is: Am I doing this the right way and if I am why does it crash?
It turns out I wasn't deleting a particle emitter so I put in a bit of code to delete it just before the transition and it worked.
If you do, it should work:
let reveal = SKTransition.flipHorizontalWithDuration(0.5)
let scene = GameScene(size: self.frame.size)
let skView = view as SKView!
skView.presentScene(scene, transition:reveal)
I hope this works for you.
Since you're in sprite kit , it's wrong to use :
self.view?.presentScene(scene, transition:reveal)
You should do the following :
let scene = GameScene(size: view.bounds.size)
let skView = view as SKView
//skView.showsFPS = true
//skView.showsNodeCount = true
//skView.ignoresSiblingOrder = true
//scene.scaleMode = .ResizeFill
skView.presentScene(scene, transition:reveal)