Swift spritekit更改场景?

时间:2014-11-26 16:14:27

标签: swift sprite-kit

我有一个使用SpriteKit的快速游戏。我做了一个游戏,但现在我想创建一个菜单场景。所以我改变了GameViewController来加载MenuScene.swift,就像这样

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

它加载了MenuScene就好了,我创建了一个播放按钮,但现在我想在点击时转换到gamescene,所以我输入了这段代码

    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)

        }
     }
   }

我尝试了很多其他尝试,但每次尝试都崩溃到AppDelegate.swift时出现错误:线程1:EXC_BAD_ACCESS(代码= EXC_I386_GPFLT)

那么我做错了什么?

3 个答案:

答案 0 :(得分:1)

问题出在sknode扩展部分。

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
 }
}
}

将通过创建新的skNode扩展并修改它来修复它。像:

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
   }

}                         }

它的答案非常晚,但必须有解决方案..

答案 1 :(得分:0)

使用此代码更改您的场景:

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)

}

答案 2 :(得分:0)

事实证明我在菜单场景中有一个粒子发射器。转换时我忘了删除它。所以它试图发射到一个不再存在的场景。修复它就像在转换到游戏场景之前添加此行一样简单。

myparticle.removeFromParent();