Время
Мы уже разобрались с событиями. Теперь пришло время разобраться с временем. Знание того, как обращаться с временем — ключевой момент при создании игр. В этом уроке мы создадим простой таймер, который можно запускать и останавливать.Предположим что вам нужно отмерить 30-секундный интервал, но у вас нет таймера. Если бы на стене висели часы с секундной стрелкой, вы бы дождались пока она достигнет положения кратного 15 секундам:и ждали бы до тех пор, пока она не пройдет 30 секунд от точки отсчета.Наш таймер работает по этому же принципу. SDL
запускает внутренний таймер в нашей программе, и мы можем получить время в миллисекундах используя SDL_GetTIcks()
. Если вам нужно отмерить 1000 миллисекунд, вы сохраняете время когда вы начали ожидание и ждете до тех пор, пока разница между временем начала и текущем не будет равна 1000.
//Заголовки
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include
#include
Наряду со стандартными заголовками, мы подключаем строковые потоки. Я объясню что это такое чуть позже.
int main( int argc, char* args[] )
{
//Флаг выхода
bool quit = false;
//Время начала отсчета таймера
Uint32 start = 0;
//Флаг старта/остановки таймера
bool running = true;
В начале функции main
мы объявляем две переменные, которые мы будем использовать для реализации нашего таймера. start
будет хранить время запуска таймера, а running
— флаг, отслеживающий запущен ли таймер.
//Инициализируем таймер
start = SDL_GetTicks();
//Пока пользователь не решил выйти
while( quit == false )
{
После того, как мы инициализировали и загрузили поверхности, пришло время запустить таймер.
Мы начинаем с того, что сохраняем текущее время, используя SDL_GetTicks()
. После этого мы входим в главный цикл.
//Пока есть события для обработки
while( SDL_PollEvent( &event ) )
{
//Если нажали клавишу
if( event.type == SDL_KEYDOWN )
{
//Если нажали клавишу 's'
if( event.key.keysym.sym == SDLK_s )
{
//Если таймер запущен
if( running == true )
{
//Остановить таймер
running = false;
start = 0;
}
else
{
//Запустить таймер
running = true;
start = SDL_GetTicks();
}
}
}
Здесь мы обрабатываем нажатие клавиши 's
', которая запускает и останавливает таймер. Если таймер был запущен, мы выставляем флаг running
в false
, и обнуляем start
, просто потому что я не люблю бродячие значения. Если таймер был остановлен, мы, напротив, присваиваем флагу running
значение true и запускаем таймер, так же, как мы сделали это до входа в главный цикл.
//Если таймер запущен
if( running == true )
{
//Время таймера в виде строки
std::stringstream time;
//Преобразовать время в строку
time << "Timer: " << SDL_GetTicks() - start;
После того, как мы выводим фон и сообщение, мы проверяем запущен ли таймер. Если да, то показываем время. Формула для расчета времени таймера такова:время = текущее время - время запуска
То есть, если вы запустили таймер, когда значение SDL_GetTicks()
было равно 10 000 и теперь оно 20 000, формула даст нам цифру 10 000, означающую что прошло 10 секунд с момента запуска таймера. Теперь кладем 'Timer: ' + время таймера
в строковой поток. Мы создаем строковой поток по имени time
, который хранит сообщение содержащее время таймера. Строковые потоки позволяют создавать строки из нескольких переменных. Как вы могли заметить, они очень похожи на cout
, но вместо того, чтобы выводить все в консоль, они просто сохраняют текст в строковом потоке, чтобы мы могли воспользоваться им впоследствии. Тем из вас, кто все еще пользуются VC++ 6.0, нужно будет привести (SDL_GetTicks() - start)
к int
.
//Отрисовать время
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
//Вывести время
apply_surface( ( SCREEN_WIDTH - seconds->w ) / 2, 50, seconds, screen );
//освободить поверхность
SDL_FreeSurface( seconds );
}
//Обновить экран
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}