Swift: повторять действие через случайный промежуток времени.

Раньше с Objective-C я мог использовать PerformSelector: для повторения действия через случайный период времени, который мог варьироваться в пределах 1-3 секунд. Но поскольку я не могу использовать PerformSelector: в Swift я попытался использовать «NSTimer.scheduledTimerWithTimeInterval». И работает для того, чтобы повторить действие. Но существует проблема. При задании переменной времени вызывается функция, которая будет генерировать случайное число. Но кажется, что NSTimer использует один и тот же номер каждый раз, когда повторяет действие.

Это означает, что действие выполняется не случайным образом, а через заданный период времени, который генерируется случайным образом в начале игры и используется на протяжении всей игры.

Вопрос в следующем: есть ли способ настроить NSTimer на создание случайного числа каждый раз, когда он выполняет действие? Или я должен использовать другой метод? Спасибо!


person José María    schedule 07.07.2014    source источник
comment
возможный дубликат Swift PerformSelector: withObject: afterDelay:   -  person Jack    schedule 07.07.2014
comment
что будет, если вы воссоздадите таймер в селекторе, который вызывается после запуска таймера?   -  person holex    schedule 07.07.2014
comment
используйте skactions или update:, никогда не ntimer, gcd dispatch или Performselector в наборе спрайтов или cocos2d, подробнее см. здесь: stackoverflow.com/a/ 23978854/201863   -  person LearnCocos2D    schedule 07.07.2014
comment
@LearnCocos2D Не могли бы вы помочь мне перевести этот код на Swift? Спасибо!   -  person José María    schedule 07.07.2014
comment
Свифт пока не трогал....   -  person LearnCocos2D    schedule 07.07.2014
comment
@LearnCocos2D Ох... :(   -  person José María    schedule 07.07.2014


Ответы (3)


@LearnCocos2D прав... используйте метод SKActions или update в своей сцене. Вот базовый пример использования update для повторения действия через случайный период времени.

class YourScene:SKScene {

    // Time of last update(currentTime:) call
    var lastUpdateTime = NSTimeInterval(0)

    // Seconds elapsed since last action
    var timeSinceLastAction = NSTimeInterval(0)

    // Seconds before performing next action. Choose a default value
    var timeUntilNextAction = NSTimeInterval(4)

    override func update(currentTime: NSTimeInterval) {

        let delta = currentTime - lastUpdateTime
        lastUpdateTime = currentTime

        timeSinceLastAction += delta

        if timeSinceLastAction >= timeUntilNextAction {

            // perform your action

            // reset
            timeSinceLastAction = NSTimeInterval(0)
            // Randomize seconds until next action
            timeUntilNextAction = CDouble(arc4random_uniform(6))

        }

    }

}
person Jon    schedule 08.07.2014
comment
Какой аргумент я должен передать при вызове метода self.update? Спасибо за Ваш ответ! - person José María; 08.07.2014
comment
Кроме того, как мне отсрочить действие? Я имею в виду, если я использую это, действие выполняется в начале, когда сцена загружается. Как я могу отложить обновление, скажем, на 10 секунд после загрузки сцены? Спасибо! - person José María; 08.07.2014
comment
Вы никогда не будете вызывать метод обновления напрямую. На этом изображении показано, в каком порядке оцениваются действия сцены: developer.apple.com/library/ios/documentation/GraphicsAnimation/ - person Jon; 08.07.2014
comment
Здесь также будет полезен обзорный раздел: developer.apple.com/library/ios/documentation/SpriteKit/ - person Jon; 08.07.2014
comment
Еще один вопрос. Что, если я хочу запланировать действие, которое произойдет позже в игре? Например, если у меня есть одна бомба, сбрасываемая при запуске игры, я хочу две бомбы, когда пользователь играет в течение 20 секунд или имеет более 15 очков. Я мог бы сделать это с помощью PerformSelector afterDelay:x. Как я мог сделать это здесь? - person José María; 09.07.2014
comment
Думайте о методе обновления как о часах. Он всегда отправляет вам текущее время. Вам решать, что вы хотите делать с информацией о текущем времени. Если вы хотите сбросить бомбу через 20 секунд после начала игры, создайте переменную для хранения времени начала игры и отслеживайте, сколько секунд прошло, используя ваши часы (currentTime). Короче говоря, вам просто нужны переменные и операторы IF. - person Jon; 09.07.2014
comment
О, интересно. Я должен провести расследование. Спасибо за информацию и вашу помощь! - person José María; 10.07.2014

используйте let wait = SKAction.waitForDuration(sec, withRange: dur) в своем коде. SKAction.waitForDuration с параметром withRange будет вычислять случайный интервал времени со средним временем = сек и возможным диапазоном = dur

person Artem Lytaev    schedule 18.08.2015

Создайте случайное время самостоятельно и используйте dispatch_after для выполнения действия.

Дополнительные сведения о dispatch_after см. здесь. В основном вы можете использовать это вместо performSelector

person Roshan    schedule 07.07.2014