2016-04-19 10 views
1

私はプレーヤの背景を背景にした単純なゲームに取り組んでいます。左右のコーナーには、文字を左右に動かすボタンがあります。私はすでにそれを実装しています(キャラクターは動いており、背後にペイントされた背景が残っています)が、別のサークルfpsのドロップを本当に速く追加しています。それには解決策はありますか?複数の円を描いたSpriteKit

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 
    } 
} 

EDIT: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 
    } 
} 
+0

'SKShapeNode'は、' SKSpriteNode'のようにバッチでレンダリングされません。作成するシェイプノードごとに少なくとも1回の描画呼び出しが必要です(現在のパフォーマンスの問題の原因です)。 。ご覧のとおり、ドキュメントに従って[SKShapeNode](https://developer.apple.com/library/mac/documentation/SpriteKit/Reference/SKShapeNode_Ref/)は控えめに使用する必要があります。 – Whirlwind

+0

@Whirlwindだから私はSKShapeNodeを何か他のものに置き換えることができる他の解決策がありますか?私はSK SpriteNodeを円のイメージで使用するとノードの数が多いために – user1483208

+0

@WhirlwindがSKShapeNodeをSKSpriteNodeに置き換えた後、約300ノードのフレームレートを追加した後にもドロップすると思います – user1483208

答えて

0

に置き換えます。コードを最適化する必要があります。インストゥルメント(Time Profiler)を使用して、どのライン/ファンクションが問題の原因となっているかを調べます。 WWDCビデオを見てみることをお勧めします。Profiling In-Depth

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 
    } 
} 

この方法であなたは引き分けの数が減少している(代わりにSKShapeNodeSKSpriteNodeを使用することによって)すべてのサークルをレンダリングするために必要な呼び出し。また、同じテクスチャを再利用しているため、imageNamedを使用するたびに割り当てる代わりに、アプリが消費するメモリ量が大幅に削減されています。これらのノードがバッチでレンダリングされる場合、SpriteKitは何百というノードを@ 60 fpsでレンダリングできます。 fpsが低下する前にはまだ限界があります。それはデバイスに依存します。