BARIIIIIIICODE BARIIIIIIICODE - 4 months ago 19
Swift Question

Optimizing code Physics

I have been trying to optimize code to lower my cpu usage. I have rewritten these functions a couple of times to no avail, looking for some assistance.

63% of time spent on for ball in ... line which only has at most 24 children.

func totalMass() -> CGFloat {
var ret : CGFloat = 0
for ball in self.children as! [Ball] {
ret += ball.mass
}
return ret
}


almost 90% of time spent on the if distance(food...) there can be over 800 pieces of 'food' at one time.

func randomMove() {
confidenceLevel = 0
if let b = self.children.first as! Ball? {
if b.physicsBody?.velocity == CGVector(dx: 0, dy: 0) {
//print("a")
self.move(randomPosition())
} else if b.position.x + b.radius > 1950 || b.position.x - b.radius < -1950 {
//print("here", b.position.x, b.radius)
self.move(randomPosition())
} else if b.position.y + b.radius > 1950 || b.position.y - b.radius < -1950 {
//print("there")
self.move(randomPosition())
} else {
// Keep moving
let scene : GameScene = self.scene as! GameScene
for food in scene.foodLayer.children as! [Food] {
if distance (food.position, p2: self.centerPosition()) < b.radius * 5 {
self.move(food.position)
return
}
}
}
}
}


100% of the time spent on the closing curly brace line }) before the third IF statment

override func didSimulatePhysics() {

world.enumerateChildNodesWithName("//ball*", usingBlock: {
node, stop in
let ball = node as! Ball
ball.regulateSpeed()
if let body = ball.physicsBody {
if (body.velocity.speed() > 0.01) {
ball.zRotation = body.velocity.angle() - self.offset
}
}
})

if let p = currentPlayer {
centerWorldOnPosition(p.centerPosition())
} else if playerLayer.children.count > 0 {
let p = playerLayer.children.first! as! Player
centerWorldOnPosition(p.centerPosition())
} else {
centerWorldOnPosition(CGPoint(x: 0, y: 0))
}
}

Answer

Use of the distance formula in this manner can be an expensive operation, If you do not need the actual distance, I would recommend you use distance squared

func randomMove() {
        confidenceLevel = 0
        if let b = self.children.first as! Ball? {
            if b.physicsBody?.velocity == CGVector(dx: 0, dy: 0) {
                //print("a")
                self.move(randomPosition())
            } else if b.position.x + b.radius > 1950 || b.position.x - b.radius < -1950 {
                //print("here", b.position.x, b.radius)
                self.move(randomPosition())
            } else if b.position.y + b.radius > 1950 || b.position.y - b.radius < -1950 {
                //print("there")
                self.move(randomPosition())
            } else {
                // Keep moving
                let bRadiusSqr = b.radius * 5 * b.radius * 5
                let selfPosition = self.centerPosition()
                let scene : GameScene = self.scene as! GameScene
                for food in scene.foodLayer.children as! [Food] {
                    let diffX = food.position.x - selfPosition.x
                    let diffY = food.position.y - selfPosition.y 
                    if diffX * diffX + diffY * diffY < bRadiusSqr  {
                        self.move(food.position)
                        return
                    }
                }
            }
        }
    }