Почему вызов случайной функции не работает в последовательности?

Я пытаюсь сгенерировать случайную позицию X для простого объекта, чтобы он подпрыгивал назад и вперед внутри сцены в игре Swift SpriteKit. Действие repeatForever должно генерировать случайное значение, а затем перемещать объект (круг) несколько раз в разные места, влево и вправо. Однако действует только один раз. Как будто случайная функция, которая работает правильно, вызывается только один раз, и действие просто продолжает перемещать объект в одну и ту же позицию навсегда.

let circle = SKSpriteNode(imageNamed: "circle")
circle.run(SKAction.repeatForever(SKAction.move(to:
        CGPoint(x: random(min: minCircleX, max: maxCircleX),
            y: scene.size.height*0.5),
            duration: 0.5)))

Круг перемещается только один раз, в одну позицию, и, кажется, после этого никогда не перемещается. Я подозреваю, что он просто перемещается в одну и ту же позицию снова и снова. Спасибо за любые предложения!

2 ответа

Хорошо, после нескольких усилий, работает следующее:

let customAction = SKAction.customAction(withDuration: 1000)
{
    circle, _ in
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                        y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5))
}
circle.run(customAction)

Дай был прав, предложив анонимную функцию. Метод SKAction customAction позволяет это сделать. И затем выполнение действительного действия внутри функции гарантировало, что движение было случайным каждый раз. Спасибо!

Вместо того, чтобы повторяться вечно, используйте блок завершения, чтобы установить новый шаг:

func newLocation(){
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                    y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5){
       [weak self] in self?.newLocation()
    }
}

После завершения перемещения, он добавит новое перемещение и следующее случайное местоположение. Единственный недостаток - это то, что он начнет следующий ход в том же кадре, что и текущий ход, так как это делается на этапе действия обновления. Если вы не хотите этот эффект, то вам нужно сохранить его в блоке, который будет сделан во время didFinishUpdate

var  finishedUpdates = [()->()]()
func newLocation(){
    let newXLocation: CGPoint = CGPoint(x: random(min: minCircleX, max: maxCircleX),
                                        y: scene.size.height*0.5)
    circle.run(SKAction.move(to: newXLocation, duration: 0.5){
       [weak self] in 
       self?.finishedUpdates.append({weak self] in self?.newLocation()})
    }
}


func didFinishUpdate()
{
    finishedUpdates.forEach{$0()}
    finishedUpdates = [()->()]() //Be sure to clear the array
}

Мои извинения заранее, это написано только из памяти, и может быть не на 100% синтаксически правильным

Другие вопросы по тегам