Oliver Reznik - 1 year ago 97
Swift Question

# How do I position a node to a random point on a circle's perimeter in Sprite Kit?

So I need to spawn game enemies from random points on the perimeter of a circle. This is the code I have so far which feels really close to working but isn't:

``````let enemy = SKShapeNode(circleOfRadius: 5)

func enemyGenerator() {

//takes an x value and calculates the corresponding y coordinate on the circle.
func enemyYSpawnPosition(x: CGFloat) -> CGFloat {
return sqrt(104006.25 - (x * x))
}

//randomly selects an x value from a range of acceptable values.
func enemyXSpawnPosition() -> CGFloat {
func randRange (lower: Int , upper: Int) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
}
var xValue = randRange(-2.5, 322.5)
return CGFloat (xValue)
}

//used to randomly decide whether the y value will be subtracted or added.
func coinFlip (lower: Int, upper: Int) -> Int {
return lower + Int(arc4random_uniform(UInt32(upper - lower + 1)))
}
var randResult = coinFlip(1, 2)

//positions the enemy using the functions above.
if randResult == 1 {
self.enemy.position = CGPointMake(enemyXSpawnPosition(), CGRectGetMidY(self.frame) + enemyYSpawnPosition(enemyXSpawnPosition()))
}
else {
self.enemy.position = CGPointMake(enemyXSpawnPosition(), CGRectGetMidY(self.frame) - enemyYSpawnPosition(enemyXSpawnPosition()))
}
}
``````

The issue is that when positioning the enemy I must call the enemyXSpawnPosition function twice and when I do that I get two different values. When I'm laying out the positions I need the values to stay the same.

Is there an easier way to randomly position a node on a circle's perimeter or is their a way to fix what I've already got?

This method returns a random point on a circle given the circle's radius and center position.

``````    func randomPointOnCircle(radius:Float, center:CGPoint) -> CGPoint {
// Random angle in [0, 2*pi]
let theta = Float(arc4random_uniform(UInt32.max))/Float(UInt32.max-1) * Float(M_PI) * 2.0
// Convert polar to cartesian
let x = radius * cosf(theta)
let y = radius * sinf(theta)
return CGPointMake(CGFloat(x)+center.x,CGFloat(y)+center.y)
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download