Таймеры различных типов используются во всех играх. Они являются важной частью игровых циклов. Таймеры используются для периодической перерисовки экрана, обновления позиций спрайтов, а также участвуют в обработке многих других игровых событий.

Разрешающая способность таймеров в Symbian OS не велика, но ее вполне достаточно для типичных целей - таймеры ядра обеспечивают точность 1/64 секунды на устройстве и 1/10 на эмуляторе (Чтобы узнать фактическое значение, используйте UserHal::TickPeriod). Данный интервал округляется вверх до самого близкого значения разрешающей способности частоты сигнала системного времени.

Ниже приведенывиды таймеров, применяемых в Symbian OS:

  • Простой таймер, реализуемый RTimer, обеспечивает генерацию событий после заданного промежутка времени или в определенное время. RTimer обеспечивает самый низкий уровень доступа к системному таймеру. Этот таймер можно использовать, когда движок игры пишется с использованием Active Objects.

  • Периодический таймер (CPeriodic) генерирует события периодически через определенный промежуток времени. Сообщение передается приложению через обратный вызов (TCallBack), который задается при создании таймера. Именно этот таймер наиболее широко используется в играх. Он очень прост, и, как правило, для игры хватает одного таймера.

  • Таймер биения (CHeartBeat) подобен периодическому, но имеет некоторые дополнительные возможности. Он использует обратный вызов для информирования о пропуске события таймера (то есть о том, что таймер не обработан во время). CPeriodic неточен. Он задерживает события пока приложение не будет готово его обработать.

Дополнительные возможности таймера биения (информирование о пропущенных событиях MBeating::Synchronize) редко используются, поскольку игры, как правило, не требуют очень точной синхронизации. Обычно нужно знать только время, прошедшее с предыдущего вызова. Точное время необходимо, например, чтобы рассчитать новое положение спрайта, основываясь на его предыдущем положении и скорости движения. Небольшая погрешность таймера не оказывает существенного влияния на результат.

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

// запуск таймера
void CMyGameView::StartTimerL()
{
// интервал в миллисекундах; 100000 соответствует 1/10 секунды
const TInt KTickInterval=100000;
iPeriodic= CPeriodic::NewL(CActive::EPriorityLow);
iPeriodic->Start(KTickInterval, KTickInterval,TCallBack(Tick, this));
}
 
// Останавливаем таймер
void CMyGameView::StopTimer()
{
iPeriodic->Cancel();
delete iPeriodic;
iPeriodic=NULL;
}
 
// Вызывается таймером по прошествии заданного интервала.
// Этот метод должен быть статическим
TInt CMyGameView::Tick(TAny* aObject)
{
// вызываем не статический метод
((CMyGameEngine*)aObject)->NextTick();
// позволяем таймеру продолжить его работу
return1;
}
// нестатическое событие таймера, вызываемое статическим Tick()
void CMyGameView::NextTick()
{
TTime currentTime;
currentTime.HomeTime();
TInt64 currentTick= currentTime.Int64();
// Вычисляем время, прошедшее с послдеднего вызова в миллисекундах
// iLastTick текущее время с момента предыдущего срабатываения таймера
TInt64 frameTime= currentTick- iLastTick;
iLastTick= currentTick;
// Обновляем экран согласно frameTime
switch(iGameState)
{
case EPlayingTheGame:
// Вычисляем положение спрайта и перерисовываем экран
HandleGameTick(frameTime);
break;
case EWatchingTheIntro:
// Заставка к игре может обрабатываться этим же таймером
HandleIntroTick(frameTime);
break;
// Здесь же могут обрабатываться любые другие состояния игры
}
}

Использования нескольких таймеров обычно не требуется. Это делает структуру игры не такой наглядной, и может вызвать разные неприятные эффекты, особенно если несколько таймеров используются в одном игровом состоянии. Поскольку таймеры используют Active Object, на Active Scheduler ложиться дополнительная нагрузка, кроме того расходуются системные ресурсы.

Приоритет таймера и загруженность Active Scheduler сказывается на точности таймера. Вы не должны перегружать задачами планировщика. События таймера должны обрабатываться как можно быстрее. Таймер должен иметь низкий приоритет, а интервал таймера должен быть по возможности велик. Эти предосторожности позволят избежать ошибок, когда планировщик не справляется с входящими событиями и приложение начинает тормозить.


Перевод:aRix.




Наши соцсети

Подписаться Facebook Подписаться Вконтакте Подписаться Twitter Подписаться Google Подписаться Telegram

Популярное

Ссылки

Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3]) Android / Архив

Рейтинг@Mail.ru Яндекс.Метрика
MobiLab.ru © 2005-2018
При использовании материалов сайта ссылка на www.mobilab.ru обязательна