当前位置:  开发笔记 > 编程语言 > 正文

使用presentScene()更改SKScene

如何解决《使用presentScene()更改SKScene》经验,为你挑选了1个好方法。

在我使用的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))

从一个场景移动到另一个场景.但是我怎样才能回到原来的场景呢?使用相同的代码原则总是导致严重的崩溃..



1> Whirlwind..:

我举了一个例子,用全局结构跟踪信息previousScene.它也可以使用自定义属性,或者使用每个节点都有的userData.逻辑是一样的.此外,我已经删除了调试代码(调试标签代码等),因为它对于一切工作并不重要.

如果我添加几个按钮,每个链接到特定场景,示例可能会更好,但我只留下一个按钮,以尽可能缩短所有内容.

您需要了解的关于此示例的内容(您将根据您的游戏更改此规则,但逻辑是相同的 - 在实际转换之前设置previousScene):

有三个场景,WelcomeScene(默认一个),MenuScene和GameScene.

点击黑色按钮将带您进入GameScene.当前场景是GameScene时,此规则有一个例外.在这种情况下,转换将带您到previousScene.

点击黑色按钮周围的任何地方都可以转到上一个场景.首次加载WelcomeScene时,此规则有一个例外(previousScene未设置),在这种情况下转换将带您进入MenuScene.

- 在你的GameViewController中,你应该将WelcomeScene设置为默认值.否则,您应该稍微更改一下代码以处理未设置previousScene时发生的情况(就像我在toussBegan的WelcomeScene中所做的那样).

所以这些是我制定的规则,只是为了让所有这些过渡更有意义......

这是代码(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,GameScene)都继承自BaseScene类(它是SKScene的子类).我想,没有必要解释这个问题,但可以随意问一下是否有什么东西让你困惑.这里的重要方法(由每个子类使用)是goToScene(scene:SceneType)及其参数(类型为SceneType),它告诉我们方法应该加载什么类型的场景.

SceneType只是一个包含整数的枚举...所以实际上我们不在这里使用对象,因此不用担心强引用周期.

接下来,还有其他场景(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, 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, 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, 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)  
        }
    }
}

预习:

过渡

只需从头开始再读一遍规则就可以了(例如,在GameScene黑色按钮不起作用,或者在第一次启动时没有设置previousScene,所以默认情况下你将转换到MenuScene).

就是这样.希望这个对你有帮助.您可以复制并粘贴代码以对其进行测试,并根据您的需要进行改进.不过,还不确定你真的需要这个.看起来你只需要在场景之间正确转换.

提示:这里重要的是每个场景BaseScene,WelcomeScene ......都有自己的.sks文件.您可以从File-> New-> File-> Resource创建它们并对其进行适当的命名(如BaseClass.sks,WelcomeScene.sks ......)此外,维护GlobalData.previousScene变量状态是您的工作(例如,在转型).

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有