Swift Infinite Scroller FPS代码效率低下

时间:2015-12-08 05:22:13

标签: ios swift sprite-kit

我在制作无限卷轴时遇到问题。谷歌的结果表明,我必须使用效率低下的代码,因为我在模拟器和iPhone 5(物理设备)上获得了大约14-15 FPS,我得到了相同的结果。我希望有一些提高我的代码效率的技巧。合并功能可能呢?缩小图像并缩放图像? 当前的背景图片是1136x750。 平台大约是200x75。

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    let screenSize: CGRect = UIScreen.mainScreen().bounds
    let backgroundVelocity : CGFloat = 6.0


    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        self.backgroundColor = SKColor.whiteColor()
        self.initializingScrollingBackground()
        self.startPlatforms()


        // Making self delegate of physics world
        self.physicsWorld.gravity = CGVectorMake(0, 0)
        self.physicsWorld.contactDelegate = self
    }


        override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

        self.moveBackground()
        self.movePlatforms()
    }

    func startPlatforms(){
        for var n = 0; n < 1000; ++n {
        let plat = SKSpriteNode(imageNamed: "platform")
        plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
        plat.anchorPoint = CGPointZero
        plat.name = "platform"
        self.addChild(plat)

        }

    }
    func movePlatforms() {
        self.enumerateChildNodesWithName("platform", usingBlock: { (node, stop) -> Void in
            if let plat = node as? SKSpriteNode {
                plat.position = CGPoint(x: plat.position.x - self.backgroundVelocity, y: plat.position.y)
                if(plat.position.x <= -200 ){
                        node.removeFromParent()

                }
            }
        })
    }


    func initializingScrollingBackground() {
        for var index = 0; index < 2; ++index {
            let bg = SKSpriteNode(imageNamed: "bg")
            bg.position = CGPoint(x: index * Int(bg.size.width), y: -55)
            bg.anchorPoint = CGPointZero
            bg.name = "background"
            self.addChild(bg)
        }

    }

    func moveBackground() {
        self.enumerateChildNodesWithName("background", usingBlock: { (node, stop) -> Void in
            if let bg = node as? SKSpriteNode {
                bg.position = CGPoint(x: bg.position.x - self.backgroundVelocity, y: bg.position.y)

                // Checks if bg node is completely scrolled off the screen, if yes, then puts it at the end of the other node.
                if bg.position.x <= -bg.size.width {
                    bg.position = CGPointMake(bg.position.x + bg.size.width * 2, bg.position.y)
                }
            }
        })
    }

}

1 个答案:

答案 0 :(得分:4)

写游戏时要记住的一个基本事实:

  

您想要从更新方法运行的每个代码(所以每帧)   必须

现在,让我们来看看你的代码。

1。分组节点

如果你有一堆节点移动到一个节点,而不是手动移动每个节点,你应该为它们添加一个共同的parent,然后只移动parent

所以这个

func startPlatforms(){
    for var n = 0; n < 1000; ++n {
        let plat = SKSpriteNode(imageNamed: "platform")
        plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
        plat.anchorPoint = CGPointZero
        plat.name = "platform"
        self.addChild(plat)
    }
}

变成这个

private let platformParent = SKNode()
func createPlatforms() {
    self.addChild(platformParent)
    for n in 0...999 {
        let plat = SKSpriteNode(imageNamed: "platform")
        plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
        plat.anchorPoint = CGPointZero
        plat.name = "platform"
        platformParent.addChild(plat)
    }
}

2。使用SKAction移动

现在您不需要移动每个平台,您可以运行仅移动父级的SKActionchildren将自动关注他。

所以这个

func movePlatforms() {
    self.enumerateChildNodesWithName("platform", usingBlock: { (node, stop) -> Void in
        if let plat = node as? SKSpriteNode {
            plat.position = CGPoint(x: plat.position.x - self.backgroundVelocity, y: plat.position.y)
            if(plat.position.x <= -200 ){
                node.removeFromParent()

            }
        }
    })
}

变成这个

// to be called only once!
func beginMovingParentPlatform() {
    let moveToLeft = SKAction.moveToX(-200, duration: 5) // please change the 2 params (-200 and 5) as you need
    self.platformParent.runAction(moveToLeft) {
        self.removeAllChildren()
    }
}

当然这个

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

    self.moveBackground()
    self.movePlatforms()
}

变成这个

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

    self.moveBackground()
    // self.movePlatforms()
}

现在你的代码应该更快。

您可以将相同的逻辑应用于moveBackground

请记住,不要手动移动节点。使用SKActions,它们比您(或我)可以编写的代码更加优化。