HarveyBrCo
HarveyBrCo

Reputation: 825

Swift spritekit change scenes?

I have a swift game that uses SpriteKit. I made a game but now I want to create a menu scene. So I changed the GameViewController to load MenuScene.swift like so

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 MenuScene
        archiver.finishDecoding()
        return scene
    } else {
        return nil
    }
  }


}

class GameViewController: UIViewController {



override func viewDidLoad() {
    super.viewDidLoad()

    if let scene = MenuScene.unarchiveFromFile("MenuScene") as? MenuScene {
    //if scene = MenuScene.unarchiveFromFile("MenuScene") as? MenuScene {
        // 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

        scene.size = skView.bounds.size

        skView.presentScene(scene)
    }
}

It loads MenuScene just fine and I created a play button but now I want to transition to gamescene when clicked so I put in this code

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */

    for touch: AnyObject in touches {

        let location = touch.locationInNode(self)

        if(play.containsPoint(location)) {



            gamescene = GameScene(size: self.scene!.size)
            self.view!.presentScene(gamescene, transition:reveal)

        }
     }
   }

I have tried numerous other attempts but each time it has crashed into AppDelegate.swift with the error: Thread 1: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)

So what am I doing wrong?

Upvotes: 1

Views: 1447

Answers (3)

HarveyBrCo
HarveyBrCo

Reputation: 825

It turns out I had a particle emitter in the menu scene. I forgot to remove it when transitioning. So it was trying to emitting to a scene that did not exist anymore. Fixing it was as simple as adding this line before transitioning to the game scene.

myparticle.removeFromParent();

Upvotes: 0

gabrielpf
gabrielpf

Reputation: 332

Use this code for change your scene :

func changeScene(){
    let scene =  NameScene(size: self.view!.bounds.size)
    scene.backgroundColor = SKColor(red: 1, green: 1, blue: 1, alpha: 1)
    scene.scaleMode = .AspectFill
    scene.backgroundColor = UIColor.whiteColor()
    let transition = SKTransition.pushWithDirection(SKTransitionDirection.Left, duration:0.5)
    self.scene?.view?.presentScene(scene, transition: transition)

}

Upvotes: 0

Antiokhos
Antiokhos

Reputation: 3055

the problem is in sknode extension part.

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")

/*
Below Line is the problem. you create an object with gameScene object 
    type However in here you call it as MenuScene. 
    */
        let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as MenuScene
        archiver.finishDecoding()
        return scene
 } else {
        return nil
 }
}
}

it will be fixed with creating new skNode extension and modified it . like as:

extension SKNode {
   class func unarchiveFromFile2(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
   }

} }

Its very late answer but there must be solution..

Upvotes: 1

Related Questions