更改自定义 spritenode 类上的纹理会降低帧速率,但只是第一次?

问题描述 投票:0回答:1

我现在正在开发一个游戏,在该游戏中,当触发时,我的自定义 spritenode 子类 FireAlarm 会执行一个功能,它会两次更改其纹理并生成一个“爆炸”节点。这非常有效,除了第一次在游戏中发生时,游戏会明显滞后。延迟的根源似乎是 FireAlarm 纹理的变化,我尝试了很多不同的方法来使用单例类和其他策略来预加载纹理,但似乎没有任何方法可以解决它。我觉得很奇怪,这只发生在第一次,然后似乎工作正常,是我遗漏了什么吗?

class FireAlarm: SKSpriteNode {
var isOccupied: Bool = false
var firstTexture = SKTexture(imageNamed: "fireAlarm")
var pulledTexture = SKTexture(imageNamed: "fireAlarmPulled")
var charredTexture = SKTexture(imageNamed: "fireAlarmCharred")
... 

func occupy() {
  
print("occupying alarm")
isOccupied = true
        
let quickDelay = SKAction.wait(forDuration: 1.85)
let explosionAction = SKAction.run {
self.addExplosion()}
        
let sequence = SKAction.sequence([quickDelay, explosionAction])
self.run(sequence)
let delayAction = SKAction.wait(forDuration: 1.0)
let changeTexture1 = SKAction.run {
self.texture = self.pulledTexture}
let changeTexture2 = SKAction.run {
 self.texture = self.charredTexture
 }
   
    let finalSequence = SKAction.sequence([delayAction, changeTexture1, delayAction, changeTexture2])
    self.run(finalSequence){
    self.isAlive = false
    self.shadow.removeFromParent()
    
    
    }
    
swift sprite-kit textures lag skspritenode
1个回答
0
投票

您没有预加载纹理

我尝试了很多不同的方法来使用单例类和其他策略来预加载纹理,但似乎没有什么可以解决它。

我看到你声明了纹理的一些实例属性

var firstTexture = SKTexture(imageNamed: "fireAlarm")
var pulledTexture = SKTexture(imageNamed: "fireAlarmPulled")
var charredTexture = SKTexture(imageNamed: "fireAlarmCharred")

但这不是纹理预加载。事实上,SKTexture(imageNamed:)

初始化程序仅创建一个引用,真正的图像加载和准备工作稍后完成。

新的纹理对象使用图像文件的名称进行初始化,然后控制立即返回到您的游戏。 Sprite Kit 在您的游戏需要时加载并准备纹理数据。

https://developer.apple.com/documentation/spritekit/sktexture/1520086-init

解决方案

使用SKTextureAtlas预加载纹理。

这是一个例子。

class GameScene: SKScene { let textureAtlas = SKTextureAtlas(dictionary: [ "fireAlarm": UIImage(named: "fireAlarm")!, // Force unwrapping only for demonstration purposes. "fireAlarmPulled": UIImage(named: "fireAlarmPulled")!, "fireAlarmCharred": UIImage(named: "fireAlarmCharred")! ]) override func didMove(to view: SKView) { textureAtlas.preload { print("Now the textures are preloaded and you can start your game.") } } }

请注意,textureAtlas.preload 方法是异步的。

预加载完成后,就可以在游戏中使用了。

class FireAlarm: SKSpriteNode { func occupy() { guard let gameScene = self.scene as? GameScene else { fatalError() } // ... let changeTexture1 = SKAction.run { self.texture = gameScene.textureAtlas.textureNamed("fireAlarmPulled") } let changeTexture2 = SKAction.run { self.texture = gameScene.textureAtlas.textureNamed("fireAlarmCharred") } } }
请告诉我这是否可以解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.