2014-12-23 2 views
0

Внутри моей сцены я переопределил функцию -(void) update: (CFTimeInterval) currentTime по умолчанию. Стоит отметить, что переменная currentTime на самом деле является истекшим временем с начала предположительно произвольного системного времени, в отличие от прошедшего времени с момента последнего кадра. Эта функция обновления проходит через все мои символы и применяет их движение, основанное на скорости в секунду и прошедшем времени с момента последнего обновления в секундах. Обычный способ получить прошедшее время с момента последнего обновления в секундах - это иметь NSTimeInterval в вашем классе, в котором хранится последнее обновление, и вычитать последнее время обновления с текущего времени обновления, истекшие секунды. Однако начальное истекшее время не равно нулю. Таким образом, вычитание нуля из очень большого числа дает воспринимаемое истекшее время в течение многих десятков тысяч секунд. Таким образом, любые персонажи, уже находящиеся в движении на самом первом кадре, будут перемещаться очень далеко.Получение начального истекшего времени SpriteKit

Очевидным решением для этого было бы установить последнее время обновления до истечения начального времени. Тем не менее, я не вижу никакого способа получить доступ к этому в пределах SKScene, а точнее в пределах -(void) didMoveToView: (SKView *) view.

Другим решением было бы установить начальный CFTimeInterval на отрицательное число, например -1. Затем можно проверить каждую функцию обновления, будет ли время -1. Если это так, можно установить истекшее время с момента последнего обновления до 0, иначе можно было бы сделать обычный elapsedTime = currentTime - lastUpdate. Тем не менее, делая эту инструкцию if, каждая функция обновления кажется беспорядочной и ненужной.

Есть ли другие способы найти это прошедшее время с момента последнего обновления точно?

+0

Если ваша игра не является симуляцией в реальном времени, имеет ли смысл использовать временной интервал таким образом? Если игра пропускает обновление или два, имеет ли смысл заставить персонажей мгновенно перейти на новую позицию? Это справедливо для пользователя? Кроме того, что происходит с истечением времени, когда пользователь нажимает кнопку «Домой», а затем перезапускает игру позднее? – Epsilon

ответ

0

Вы правы, что проверка на флаге каждой итерации расточительно, так что вопрос о том, что это наиболее эффективный решение.

Я бы подумал, что лучшее (прочитанное: наиболее эффективное) решение заключается в том, чтобы не вносить никаких изменений в первый update, кроме простого сохранения переменной currentTime. Это не должно влиять на ваш игровой процесс; никто не заметит, что кадр был сброшен. Вы можете сделать это, сохранив указатель на функцию, вызывая эту функцию в первой итерации update, которая также изменит указатель на другую функцию, а затем update вызовет вторую функцию с этой точки вперед.

Метод, который я думаю, что вы ищете является CFAbsoluteTimeGetCurrent, но метод SK в update стремится передать обратно другое, более раннее время, вероятно из-за количества времени, затраченного на скоротать время в update по сравнению с использованием только CFAbsoluteTimeGetCurrent. Если у вас все в порядке с небольшими лишними накладными расходами без использования if, не обращайте внимания на currentTime и всегда используйте CFAbsoluteTimeGetCurrent в своем методе update.

С другой стороны, если вы беспокоитесь о накладных расходах одного оператора if в каждом фрейме, вы не будете использовать фреймворк. 60 if в секунду - это тривиальная работа даже для самого медленного мобильного процессора.

+0

Это действительно похоже на преждевременную оптимизацию. Я сомневаюсь, что его игра замедляется из-за этой проблемы. Это признанный способ проверить различия во времени. Если это не сломано, зачем это исправлять? – hamobi

+0

@hamobi Я исправляю это не только для эффективности, но и для чистоты. Не очень привлекательно иметь оператор if в вашей основной функции обновления, которая будет действительна только один раз. –

+0

его до вас. я просто думаю, что если он будет достаточно хорош для ребят из яблока, которые создали фреймворк, то он, вероятно, достаточно хорош для всех нас. – hamobi

0

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

if self.last_update_time == 0.0 { // this is the important part 
    self.delta = 0 
} else { 
    self.delta = currentTime - self.last_update_time 
} 

self.last_update_time = currentTime 

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

надеюсь, что это было полезно

+0

Он сказал, что уже рассмотрел этот подход, он просит другие возможные решения. – jonogilmour