在我的spritekit游戏中,我使用:

    self.scene!.removeFromParent()
    let skView = self.view! as SKView
    skView.ignoresSiblingOrder = true
    var scene: PlayScene!
    scene = PlayScene(size: skView.bounds.size)
    scene.scaleMode = .AspectFill
    skView.presentScene(scene, transition: SKTransition.fadeWithColor(SKColor(red: 25.0/255.0, green: 55.0/255.0, blue: 12.0/255.0, alpha: 1), duration: 1.0))

从一个场景移到另一个场景。但是我怎样才能回到最初的场景呢?使用相同的代码原理总是会导致严重的崩溃。

最佳答案

我举了一个例子,其中全局结构用于跟踪关于previousScene的信息。它也可以通过自定义属性来完成,或者通过使用每个节点都拥有的用户数据来完成。逻辑是一样的。另外,我删除了调试代码(调试标签代码等),因为它对所有工作都不重要。
如果我在每个链接到特定场景的地方添加了几个按钮,示例可能会更好,但是我只留下了一个按钮,以尽可能缩短所有内容。
关于这个例子,你需要知道什么(你将根据你的游戏改变这个规则,但是逻辑是相同的-在实际转换之前设置前一个场景):
有三个场景,welcomescene(默认)、menuscene和gamesecene。
点击黑色按钮可以进入游戏场景。当当前场景是游戏场景时,此规则有一个例外。在这种情况下,过渡将带你到上一个新的。
点击黑色按钮周围的任何地方将带你到上一个场景。当第一次加载WelcomeScene时(未设置PreviousScene),此规则有一个例外,在这种情况下,转换将带您到menuscene。
-在你的gameviewcontroller中,你应该设置一个welcomescene作为默认场景。否则,您应该稍微更改一点代码,以处理在未设置previousscene时发生的情况(就像我在WelcomeScene的Touchesbegan中所做的那样)。
所以这些都是我制定的规则,只是为了让所有这些转换更有意义…
这是代码(basescene.swift):

import SpriteKit

enum SceneType: Int {

    case WelcomeScene   = 0
    case MenuScene      //1
    case GameScene      //2
}

struct GlobalData
{
    static var previousScene:SceneType?
    //Other global data...
}

class BaseScene:SKScene {

    let button = SKSpriteNode(color: SKColor.blackColor(), size: CGSize(width: 50, height: 50))

    override func didMoveToView(view: SKView) {
        setupButton()
    }

    private func setupButton(){

        if (button.parent  == nil){

            //Just setup button properties like position, zPosition and name

            button.name = "goToGameScene"
            button.zPosition = 1
            button.position = CGPoint(x: CGRectGetMidX(frame), y: 100)
            addChild(button)
        }
    }

    func goToScene(newScene: SceneType){

        var sceneToLoad:SKScene?

        switch newScene {

        case SceneType.GameScene:

            sceneToLoad = GameScene(fileNamed: "GameScene")

        case SceneType.MenuScene:

            sceneToLoad = MenuScene(fileNamed: "MenuScene")

        case SceneType.WelcomeScene:

            sceneToLoad = WelcomeScene(fileNamed:"WelcomeScene")

        }

        if let scene = sceneToLoad {

            scene.size = size
            scene.scaleMode = scaleMode
            let transition = SKTransition.fadeWithDuration(3)
            self.view?.presentScene(scene, transition: transition)
        }
    }
}

每个场景(welcomescene、menuscene、gamesecene)都继承自一个basescene类(skscene的子类)。我想,没必要解释这一点,但如果有什么事情让你困惑的话,你可以自由地问。这里的重要方法(每个子类都使用)是gotoscene(scene:sceneType)及其参数(sceneType),它告诉我们方法应该加载哪种类型的场景。
sceneType只是一个包含整数的枚举…所以实际上我们不在这里处理对象,因此不必担心strong reference cycles
接下来,还有其他场景(welcomescene.swift):
import SpriteKit


class WelcomeScene:BaseScene {


    override func didMoveToView(view: SKView) {

        super.didMoveToView(view)

        self.backgroundColor = SKColor.darkGrayColor()
    }

    deinit {print ("WelcomeScene deinited")}

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        let touch = touches.first

        if let location = touch?.locationInNode(self){

            //Give a priority to a button - if button is tapped go to GameScene
            let node = nodeAtPoint(location)
            if node.name == "goToGameScene"{
                GlobalData.previousScene = SceneType.MenuScene
                goToScene(SceneType.GameScene)
            }else{
                //Otherwise, do a transition to the previous scene

                //Get the previous scene
                if let previousScene = GlobalData.previousScene {

                    GlobalData.previousScene = SceneType.WelcomeScene
                    goToScene(previousScene)

                }else{

                    // There is no previousScene set yet? Go to MenuScene then...
                    GlobalData.previousScene = SceneType.WelcomeScene
                    goToScene(SceneType.MenuScene)

                }
            }
        }
    }
}

为了尽可能简短,所有内容都会被注释。下一个代码(menuscene.swift):
import SpriteKit

class MenuScene: BaseScene  {

    override func didMoveToView(view: SKView) {

        super.didMoveToView(view)
        backgroundColor = SKColor.purpleColor()
    }

    deinit {
        print ("MenuScene deinited") //If this method isn't called, you might have problems with strong reference cycles.
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        let touch = touches.first

        if let location = touch?.locationInNode(self){

            //Give a priority to a button - if button is tapped go to GameScene
            let node = nodeAtPoint(location)
            if node.name == "goToGameScene"{
                GlobalData.previousScene = SceneType.MenuScene
                goToScene(SceneType.GameScene)
            }else{
                //Otherwise, do a transition to the previous scene

                //Get the previous scene
                if let previousScene = GlobalData.previousScene {

                    GlobalData.previousScene = SceneType.MenuScene
                    goToScene(previousScene)

                }
            }
        }
    }
}

最后(gamescene.swift):
import SpriteKit

class GameScene: BaseScene{

    override func didMoveToView(view: SKView) {

        super.didMoveToView(view)

     self.backgroundColor = SKColor.orangeColor()
    }

    deinit {print ("GameScene deinited")}

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        //Here, we ignore black button because we don't want to transition to the same scene

         if let previousScene = GlobalData.previousScene {

            GlobalData.previousScene = SceneType.GameScene
            goToScene(previousScene)
        }
    }
}

预览:
swift - 使用presentScene()更改SKScene-LMLPHP
只要从头再看一遍规则,你就可以了(例如,在游戏场景中,黑色按钮不起作用,或者在第一次启动时,没有设置previousscene,所以默认情况下你将转换为menuscene)。
就是这样。希望这有点帮助。您可以复制和粘贴代码来测试它,并根据需要改进它。不过,不确定你真的需要这个。看起来你只需要correctly transition between scenes
提示:这里最重要的是,每一个场景的基本场景,欢迎场景…拥有自己的.sks文件。您可以从文件->新建->文件->资源创建这些文件,并对其进行适当的命名(如baseclass.sks、welcomescene.sks…)。

关于swift - 使用presentScene()更改SKScene,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34498982/

10-10 04:09