【问题标题】:SpriteKit scene transition lag and Frame Rate drop after preloading预加载后 SpriteKit 场景过渡滞后和帧率下降
【发布时间】:2016-08-13 16:37:21
【问题描述】:

我正在使用 SpriteKit 构建游戏,最近遇到了问题,我的帧速率从 GameScene 中的 60 持续下降到 50-45,并且从我的 StartScene 打开 GameScene 时有几秒钟的延迟.我尝试了很多不同的事情,我相信我的一个主要问题与动画一个非常频繁产生的 SKSpriteNode 子类有关,当我停止动画它们并使用单个纹理时,帧速率保持在 60。我以前@ 987654321@ 关于将纹理预加载到 SpriteKit 中,并收到了很棒的答案,但我可能还没有完全理解。此时,我将所有 GameScene 纹理都放在一个 Atlas 中,并通过在 GameScene 之前为每个右侧创建常量来加载它们:

//Preload textures of GameScene before running it
let alienTexture1 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture1")
let alienTexture2 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture2")
...

class GameScene: SKScene, SKPhysicsContactDelegate {

我知道我应该使用:

SKTextureAtlas(named: "YourTextureAtlasName").preloadWithCompletionHandler { 
// Now everything you put into the texture atlas has been loaded in memory
}

预加载纹理,但我不确定括号之间的内容以及何时应该调用像 let alienTexture1 = SKTextureAtlas(named:"Sprites").textureNamed("alienTexture1") 这样的行。然后在我拥有的一些 Alien SKSpriteNode 子类的 init 中调用这些纹理。我不明白某些事情,因为预加载显然无法正常工作。我也不确定切换到GameScene 时如何处理延迟,但我想这也与我在开始时使用所有这些let 语句加载纹理的方式有关。任何建议都会很棒。

我查看了有关此主题的其他问题,并认为这足够具体,不再重复。

【问题讨论】:

    标签: ios swift debugging sprite-kit frame-rate


    【解决方案1】:

    我对此也感到困惑,我绝不是专家,但本质上预加载纹理只是意味着您将它们存储在不会被释放的数组/属性中。

    我并没有真正使用 SKTextureAtlas("").preloadWithCompletionHandler 方法。我相信这个想法基本上是一样的。

    例如你可以创建一个静态纹理加载类

     class Textures {
    
          static var alien1 = [SKTexture]() // array off all alien 1 textures
    
    
          static func preloadAll() {
               loadAlien1()
               ...
          }
    
          // Alien 1
          static func loadAlien1() {
    
               // Get atlas
               let alien1AtlasName = "Your atlas name"
               let alien1Atlas = SKTextureAtlas(named: alien1AtlasName)
    
                // Loop through images in atlas and append to alienTexture property
               // In this case there is 2 images in the atlas)
               // Images should be appended by _1 , _2 etc 
               for image in 1...2 {
                   let textureName = "\(alien1AtlasName)_\(image)"
                   let texture = alien1Atlas.textureNamed(textureName)
                   alien1.append(texture)
               }   
          }
     }
    

    当您的应用在 appDelegate 或 GameViewController 中启动时预加载纹理

     Textures.preloadAll()
    

    如果您有很多纹理并且想要保持较低的内存使用率,只需预加载您最初需要的纹理,然后为其他关卡加载其他纹理。

      Texture.loadAlien1()
    

    您可以像这样在子类或 SKScene 中的外星人 1 角色上运行动画

    let textureAnimation = SKAction.animateWithTextures(Textures.alien1, timePerFrame: 0.3)
    alien1Sprite.runAction(SKAction.repeatActionForever(textureAnimation), withKey: "Alien1AnimationKey")
    

    如果您需要清理纹理,以防不再需要它们,或者如果您的应用收到内存不足警告,您只需清空数组即可。

     Textures.alien1.removeAll()
    

    在性能方面,您还应该将图集存储在 xCode 资产目录中,这是 xCode 7 中的新功能,而不是项目中的文件夹。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多