平面动画一开始就很少冻结

时间:2017-04-30 09:38:47

标签: swift sprite-kit

除了在第一架飞机动画开始之前稍微冻结之外,还有以下代码可以正常工作。我的代码是:

enum TurnDirection: String {
    case left
    case right
    case none
}

extension GameScene {


    fileprivate func turnPlayerPlane(direction: TurnDirection) {
        let forwardAction = SKAction.animate(with: textureArray.reversed(), timePerFrame: 0.05, resize: true, restore: false)
        player.run(forwardAction) { [unowned self] in
                self.stillTurning = false
        }
    }
}

class GameScene: SKScene {

    let textureArray = [SKTexture(imageNamed: "01"),
                        SKTexture(imageNamed: "02")]

    let motionManager = CMMotionManager()
    var xAcceleration: CGFloat = 0
    var player: SKSpriteNode!
    var stillTurning = false

    override func didMove(to view: SKView) {

        performPlaneFly()
    }

    fileprivate func performPlaneFly() {
        let planeWaitAction = SKAction.wait(forDuration: 1)
        let planeDirectionAction = SKAction.run {
            self.playerDirectionCheck()
        }

        let planeSequence = SKAction.sequence([planeWaitAction, planeDirectionAction])
        let planeSequenceForever = SKAction.repeatForever(planeSequence)
        player.run(planeSequenceForever)
    }

    fileprivate func playerDirectionCheck() {
            turnPlayerPlane(direction: .right)
    }

我评论了代码的不同部分,它似乎是 turnPlayerPlane 函数,但实际上并不理解在第一次动画开始之前执行的内容如此繁重。

有人可以解释我在那里做错了吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

在开始时我已经冻结了10个小时,我找到了解决办法。而且通常的解决方案并不像看起来那么困难。因此,由于首次渲染所有纹理而导致性能下降,因此出现了冻结。纹理渲染后,我说冻结已经消失。

所以在我重写了一下我的代码后,我已经制作了单独的文件私有方法,我首先在 didMove中调用:查看以在使用之前渲染所有纹理。:

   fileprivate func planeAnimationFillArrays() {

        SKTextureAtlas.preloadTextureAtlases([SKTextureAtlas(named: "PlayerPlane")]) { [unowned self] in
            self.leftTextureArrayAnimation = {
                var array = [SKTexture]()
                for i in stride(from: 10, through: 1, by: -1) {
                    let number = String(format: "%02d", i)
                    let texture = SKTexture(imageNamed: "\(number)")
                    array.append(texture)
                }
                SKTexture.preload(array, withCompletionHandler: { 
                    print("preload is done")
                })
                return array
            }()

            self.rightTextureArrayAnimation = {
                var array = [SKTexture]()
                for i in stride(from: 10, through: 20, by: 1) {
                    let number = String(format: "%02d", i)
                    let texture = SKTexture(imageNamed: "\(number)")

                    array.append(texture)
                }
                SKTexture.preload(array, withCompletionHandler: {
                    print("preload is done")
                })
                return array
            }()
        }
    }

之前我使用了渲染我的spriteAtlas SKTextureAtlas.preloadTextureAtlases([SKTextureAtlas(名称:" XXX")])的方法,并且在此方法的完成处理程序中我使用了每个动画数组返回前的SKTexture.preload([SKTextures],completionHandler)。毕竟这些小冻结完全消失了。

现在这段代码有一些重复,但在我看来,更容易理解它在这里做了什么。希望有人发现这个解决方案很有帮助。

您知道如何减少此代码,请随意编辑或发布您自己的解决方案。

谢谢!