【问题标题】:Spritekit- Scene transition DelaySpritekit-场景转换延迟
【发布时间】:2015-05-03 15:19:15
【问题描述】:

我有一个带有按钮的主屏幕,当按下此按钮时,它应该立即转换到另一个场景,但事实并非如此。它实际上需要几秒钟。有没有办法可以预先加载该场景中的所有节点? (例如:在游戏加载画面中)

这是我的代码:

let pressButton = SKAction.setTexture(SKTexture(imageNamed: "playButtonP.png"))

            let buttonPressed = SKAction.waitForDuration(0.15)

            let buttonNormal = SKAction.setTexture(SKTexture(imageNamed: "playButton.png"))


            let gameTrans = SKAction.runBlock(){
                let doors = SKTransition.doorsOpenHorizontalWithDuration(0)
                let levelerScene = LevelerScene(fileNamed: "LevelerScene")
                self.view?.presentScene(levelerScene, transition: doors)
            }

        playButton.runAction(SKAction.sequence([pressButton,buttonPressed,buttonNormal,gameTrans]))

【问题讨论】:

    标签: swift sprite-kit skscene


    【解决方案1】:

    在呈现场景之前,您可以在 LevelerScene 中预加载您正在使用的 SKTextures。然后,一旦加载完成,您将呈现场景。这是 Apple 文档中的一个示例,已翻译为 Swift:

    SKTexture.preloadTextures(arrayOfYourTextures) {
        if let scene = GameScene(fileNamed: "GameScene") {
            let skView = self.view as! SKView
            skView.presentScene(scene)
        }
    }
    

    在你的情况下,你有几个选择:

    1. 保留一个纹理数组,您需要在 LevelerScene 中使用,您在 GameScene 中预加载:

    class LevelerScene : SKScene {
        // You need to keep a strong reference to your textures to keep
        // them in memory after they've been loaded.
        let textures = [SKTexture(imageNamed: "Tex1"), SKTexture(imageNamed: "Tex1")]
    
        // You could now reference the texture you want using the array.
    
        //...
    }
    

    现在在GameScene,当用户按下按钮时:

    if let view = self.view {
        let leveler = LevelerScene(fileNamed: "LevelerScene") 
        SKTexture.preloadTextures(leveler.textures) {
            // Done loading!
            view.presentScene(leveler)
        }
    }
    

    您无法避免等待一点点,但采用这种方法,主线程不会被阻塞,您将能够在 LevelerScene 正在加载时与 GameScene 交互。

    您也可以使用这种方法为LevelerScene 加载SKSceneGameScene 将带您进入加载场景,加载纹理,然后在完成后将您移动到 ​​LevelerScene

    重要的是要注意,因为纹理的引用在LevelerScene 中,一旦LevelerScenedeinit-ed,纹理将从内存中删除。因此,如果您想返回LevelerScene,则需要再次加载纹理。

    2. 在任何SKScenes 出现之前,您可以在GameViewController 中使用SKTexture.preloadTextures。您需要保留对这些纹理的强引用(可能在单例中),然后您可以在 LevelerScene(或应用程序中需要它们的任何其他地方)中引用它们。

    使用这种方法,因为SKTextures 存储在场景之外,所以当您转换到下一个场景时,它们不会从内存中删除。这意味着如果您离开然后返回场景,则不必再次加载纹理。但是,如果您有大量纹理占用大量内存,您可能会遇到一些内存问题。

    有关更多信息,请参阅Working with Sprites 中的将纹理预加载到内存中

    希望有帮助!

    【讨论】:

    • 那么,我可以预加载不同场景的纹理吗?
    • 我使用了第一种方法,但是仍然有一个节点需要一段时间才能出现,我做错了什么?有没有办法选择首先加载哪些纹理?
    • 只有一个节点吗?您是在didMoveToView 中添加此节点吗?针对您的问题,纹理是异步加载的,因此您将无法更改它们的加载顺序。
    • 我刚刚检查了它不仅是一个节点,而且还有 .mp3 和所有 SKLabelNodes,有没有办法可以加载所有节点?不仅仅是纹理?
    • 预加载地图集并不能解决我的问题。每个纹理都已预加载,但仍然滞后约 1 到 1.5 秒,SKTransition 未显示且不平滑。
    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多