预加载精灵工具包纹理

时间:2016-04-08 20:59:55

标签: ios swift sprite-kit textures

所以我正在阅读苹果文档中的最佳精灵套件实践。我偶然发现了这个:

例如,如果您的游戏对其所有游戏玩法使用相同的纹理,您可以创建一个在启动时运行一次的特殊加载类。您执行一次加载纹理的工作,然后将它们留在内存中。如果删除并重新创建场景对象以重新开始游戏,则不需要重新加载纹理。

这对我的应用程序中的性能有很大帮助。有人能指出我正确的方向来实现这个目标吗?

我认为我会调用一个函数在我的View Controller中加载纹理?然后访问该纹理图集?

1 个答案:

答案 0 :(得分:4)

问题是,您真的想要缓存这样的资源吗?不能说我曾经发现需要这种性质的东西。无论如何,如果以某种方式帮助您的应用程序的性能,那么您可以创建一个TextureManager类,它将是一个单例(为TextureManager类创建单独的文件),如下所示:

class TextureManager{

    private var textures = [String:SKTexture]()

    static let sharedInstance = TextureManager()

    private init(){}


    func getTexture(withName name:String)->SKTexture?{ return textures[name] }

    func addTexture(withName name:String, texture :SKTexture){


        if textures[name] == nil {
            textures[name] = texture
        }
    }

    func addTextures(texturesDictionary:[String:SKTexture]) {

        for (name, texture) in texturesDictionary {

            addTexture(withName: name, texture: texture)
        }
    }

    func removeTexture(withName name:String)->Bool {

        if textures[name] != nil {
            textures[name] = nil
            return true
        }
        return false
    }
}

在这里,您使用字典并将每个纹理与其名称相关联。非常简单的概念。如果字典中没有相同名称的纹理,则添加它。请注意过早优化。

用法:

 //I used didMoveToView in this example, but more appropriate would be to use something before this method is called, like viewDidLoad, or doing this inside off app delegate.
    override func didMoveToView(view: SKView) {

        let atlas = SKTextureAtlas(named: "game")

        let texture = atlas.textureNamed("someTexture1")

        let dictionary = [
             "someTexture2": atlas.textureNamed("someTexture2"),
             "someTexture3": atlas.textureNamed("someTexture3"),
             "someTexture4": atlas.textureNamed("someTexture4"),

        ]

        TextureManager.sharedInstance.addTexture(withName: "someTexture", texture: texture)
        TextureManager.sharedInstance.addTextures(dictionary)

    }

正如我所说,你必须将TextureManager实现放在一个单独的文件中,才能使它成为真正的单例。否则,如果您在GameScene中定义它,例如,您将能够调用该私有init,然后TextureManager将不是一个真正的单例。

因此,使用此代码,您可以在应用程序生命周期的最开始创建一些纹理,就像文档中所述:

  

例如,如果您的游戏对其所有游戏玩法使用相同的纹理,   您可以创建一个在启动时运行一次的特殊加载类。

并用它们填写字典。稍后,只要您需要纹理,就不会使用atlas.textureNamed()方法,而是从TextureManager类的字典属性加载它。此外,当在场景之间转换时,该字典将在场景的中断时存活,并且在应用程序存活时将保持不变。