多个圆圈绘制SpriteKit

时间:2016-04-19 20:57:36

标签: swift sprite-kit

我正在开发基于玩家背景的简单游戏。在左右角有一些按钮,可以将字符向左或向右移动。我已经实现了这一点(角色正在移动,背后的左侧是背景),但是添加另一个圆圈fps的速度非常快。对此有什么解决方案吗?

    import SpriteKit

class GameScene: SKScene {
    var playerDot:PlayerDot = PlayerDot(imageNamed:"player")
    var isTurningLeft:Bool = false
    var isTurningRight:Bool = false
    var lastLocation:CGPoint = CGPoint()

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        let myLabel = SKLabelNode(fontNamed:"Helvetica")
        myLabel.name = "left"
        myLabel.text = "Left"
        myLabel.fontSize = 30
        myLabel.horizontalAlignmentMode = .Left
        myLabel.position = CGPoint(x:CGRectGetMinX(self.frame), y:CGRectGetMinY(self.frame))
        self.addChild(myLabel)

        let myLabel2 = SKLabelNode(fontNamed:"Helvetica")
        myLabel2.name = "right"
        myLabel2.text = "Right"
        myLabel2.fontSize = 30
        myLabel2.horizontalAlignmentMode = .Right
        myLabel2.position = CGPoint(x:CGRectGetMaxX(self.frame), y:CGRectGetMinY(self.frame))
        self.addChild(myLabel2)

        playerDot.position = CGPoint(x:CGRectGetMaxX(self.frame)/2, y:CGRectGetMinY(self.frame))
        self.addChild(playerDot)
    }



    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInNode(self)
            if let theName = self.nodeAtPoint(location).name {
                if theName == "left" {
                   isTurningLeft = true
                    isTurningRight = false
                }
                else if theName == "right" {
                    isTurningRight = true
                    isTurningLeft = false
                }
            }
        }
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInNode(self)
            if let theName = self.nodeAtPoint(location).name {
                if theName == "left" {
                    isTurningLeft = false
                }
                else if theName == "right" {
                    isTurningRight = false
                }
            }
        }
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let location = touch.locationInNode(self)
            if let theName = self.nodeAtPoint(location).name {
                if theName == "left" {
                    isTurningLeft = false
                }
                else if theName == "right" {
                    isTurningRight = false
                }
            }
        }
    }


    override func update(currentTime: CFTimeInterval) {
        if(isTurningLeft){
            playerDot.increaseAngle()
        } else if (isTurningRight){
           playerDot.decreaseAngle()
        }
        //calculates new character position based on angle of movement changed
        playerDot.updatePosition()
        drawCircle()
    }

    func drawCircle(){
        if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
        let circle = SKShapeNode(circleOfRadius: 10 )
        circle.position = playerDot.position
        circle.fillColor = SKColor.orangeColor()
        circle.strokeColor = SKColor.orangeColor()
        self.addChild(circle)
        lastLocation = playerDot.position
        }
    }

    func distanceFromCGPoints(a:CGPoint,b:CGPoint)->CGFloat{
        return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
    }

    func random() -> CGFloat {
        return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
    }

    func random(min min: CGFloat, max: CGFloat) -> CGFloat {
        return random() * (max - min) + min
    }
}

编辑: 将SKShapeNode的drawCircle替换为SKSpriteNote

func drawCircle(){
    if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
    let playerDot2 = SKSpriteNode(imageNamed:"player")
    playerDot2.position = playerDot.position
    self.addChild(playerDot2)
    lastLocation = playerDot.position
    }
}

2 个答案:

答案 0 :(得分:0)

如果您的帧速率下降,那么代码的某些部分会降低执行速度。您需要优化代码。使用仪器(Time Profiler)快速找出导致问题的线路/功能。如果您在阅读之前从未使用它并使用它几次以获得要点,那么我建议您观看WWDC视频Profiling In-Depth

答案 1 :(得分:0)

根据您的编辑(切换到SKSpriteNode),您可以这样做:

将纹理声明为场景的属性。这样,您可以加载一次并在以后重复使用它:

let yourTexture = SKTextureAtlas(named: "yourAtlas").textureNamed("yourTexture")

然后在您的drawCircle方法中:

func drawCircle(){
    if(distanceFromCGPoints(lastLocation, b: playerDot.position)>2){
    let playerDot2 = SKSpriteNode(texture: yourTexture)
    playerDot2.position = playerDot.position
    self.addChild(playerDot2)
    lastLocation = playerDot.position
    }
}

通过这种方式(使用SKSpriteNode代替SKShapeNode),您减少了渲染所有这些圈子所需的绘制调用次数。另外,因为您重复使用相同的纹理,而不是每次使用imageNamed分配它时,您已经大大减少了应用程序消耗的内存量。现在,如果批量渲染这些节点,SpriteKit可以渲染数百个节点@ 60 fps。在fps开始下降之前仍有一个限制。这取决于设备。