Как расположить спрайт случайным образом по оси X в Swift 2

Я хотел бы, чтобы враги спавнились по оси X, пока что я получил

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

Это работает, однако я хотел бы, чтобы они появлялись на экране и не вырезались при появлении на x = 0 или максимальном x

Я также пробовал x: 100 + CGFloat(arc4random_uniform(Uint32(self.frame.width - 100)))

Это дает мне ошибку. Если ширина моего экрана, скажем, 1000, как мне сделать случайное число от 100 до 900, а также автоматически определить ширину экрана.

Я также использую SpriteKit


person Jackster    schedule 23.06.2016    source источник


Ответы (2)


В этом примере предполагается, что ваша точка привязки сцены равна 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)
}
person Ron Myschuk    schedule 23.06.2016
comment
Я пробовал как print(self.size.width), так и print(self.frame.width), когда игра запускается впервые, они оба печатают значение 1, после чего всегда 1024. Я предполагаю, что arc4random_uniform вылетает при запуске, потому что начальное значение равно отрицательный, если я вычитаю буфер. Я запускаю функцию из viewDidLoad - person Jackster; 24.06.2016
comment
На данный момент сцена еще не будет иметь информации. Попробуйте вместо этого запустить функцию переопределения func didMoveToView(view: SKView) { } - person Ron Myschuk; 24.06.2016
comment
Когда я запускаю print(self.size.width) в didMoveToView, он сначала печатает значение 1 и еще раз для 1024. Какая функция будет иметь готовую информацию в SpriteKit? - person Jackster; 24.06.2016
comment
Что-то не в порядке. Он не должен печатать дважды, у вас все еще есть оператор печати в фонде viewDidLoad? - person Ron Myschuk; 24.06.2016
comment
У меня есть оператор печати только один раз, но у меня также есть титульная сцена, и я перехожу к GameScene. - person Jackster; 24.06.2016
comment
В пустом проекте с одной сценой сразу печатается только 1024, я думаю, это как-то связано с переходом? - person Jackster; 24.06.2016

С помощью приведенной ниже математики вы можете получить случайное число между 100 и шириной кадра минус 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)

Это должно заставить ваш спрайт появиться между 900 и 100.

Спасибо Брайену Чену за этот ответ.

person Caleb Kleveter    schedule 23.06.2016
comment
не очень хороший подход, ваш код может вечно находиться в бесконечном цикле, если случайно каждое случайное число равно ‹ 100 или больше 900 - person Knight0fDragon; 24.06.2016
comment
единственная проблема в том, что вы рандомизируете y на основе ширины экрана - person Knight0fDragon; 24.06.2016
comment
1) В вопросе не указывается y. 2) Если вы не работаете в окне с соотношением сторон 1:1, ваш спрайт исчезнет с экрана. - person Knight0fDragon; 24.06.2016