0

I would like for enemies to spawn on the X axis, so far I got

enemy?.position = CGPoint(x: CGFloat(arc4random_uniform(UInt32(self.frame.width))), y: self.frame.maxY)

This works, howether I would like for them to spawn within the screen and not get cut out when spawning on x = 0 or the maximum x

I have also tried x: 100 + CGFloat(arc4random_uniform(Uint32(self.frame.width - 100)))

This give me an error, If the width of my screen is lets say 1000, how do I make a random number between 100 and 900, while also automatically finding the width of the screen.

I am also using SpriteKit

Pimgd
  • 5,983
  • 1
  • 30
  • 45
Jackster
  • 41
  • 7

3 Answers3

3

This example is assuming that your scene anchor point is 0,0

let buffer: UInt32 = 100
let randomX = randomizer(min: buffer, max: UInt32(self.size.width) - buffer)
enemy?.position = CGPoint(x: CGFloat(randomX), y: self.frame.maxY)

func randomizer(min min: UInt32, max: UInt32) -> CGFloat {

   assert(min < max)
   return CGFloat(arc4random_uniform(max - min)  + min)
}
Ron Myschuk
  • 6,011
  • 2
  • 20
  • 32
  • I tried both print(self.size.width) and print(self.frame.width) when the game first runs they both print a value of 1 after that its always 1024, Im guessing that arc4random_uniform crashes at start because the initial value is a a negative if i subtract the buffer. Im running the function from viewDidLoad – Jackster Jun 23 '16 at 23:09
  • The scene won't have the information yet at the point. Try running the function in "override func didMoveToView(view: SKView) { }" instead – Ron Myschuk Jun 23 '16 at 23:17
  • When i run print(self.size.width) in didMoveToView, It first prints the value of 1 and once more for 1024. Which function will have the information ready in SpriteKit? – Jackster Jun 23 '16 at 23:43
  • somethings not right. It shouldn't print twice, do you still have the print statement in the viewDidLoad fund as well? – Ron Myschuk Jun 23 '16 at 23:50
  • I only have the print statement once, but I also have a title scene and I'm transitioning onto the GameScene – Jackster Jun 24 '16 at 01:05
  • On a blank project with one scene it only print 1024 right away, I guess its got something to do with the transition? – Jackster Jun 24 '16 at 01:12
0

With the math below you can get a random number between 100 and the frames width minus 100:

var x = 0
var y = 0
var screenScale: CGFloat = UIScreen.mainScreen().scale()

let lower : UInt32 = 100 * Int(screenScale)
let upper : UInt32 = UInt32(self.frame.width - (100 * Int(screenScale)))

x = arc4random_uniform(upper - lower) + lower
y = arc4random_uniform(upper - lower) + lower

enemy?.position = CGPoint(x: x, y: y)

This should get your sprite to appear between 900 and 100.

Thanks to Brayen Chen for this answer.

Community
  • 1
  • 1
Caleb Kleveter
  • 11,170
  • 8
  • 62
  • 92
0
func randomRangeNumber(range: Range<Int> = 1...6) -> Int {
    let min = range.startIndex
    let max = range.endIndex
    return Int(arc4random_uniform(UInt32(max - min))) + min
}

let max = Int(self.frame.width - 100)
enemy?.position = CGPoint(x: CGFloat(randomRangeNumber(100...max)), y:self.frame.maxY)
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133