Время

12
Мы уже разобрались с событиями. Теперь пришло время разобраться с временем. Знание того, как обращаться с временем — ключевой момент при создании игр. В этом уроке мы создадим простой таймер, который можно запускать и останавливать.

Предположим что вам нужно отмерить 30-секундный интервал, но у вас нет таймера. Если бы на стене висели часы с секундной стрелкой, вы бы дождались пока она достигнет положения кратного 15 секундам:
start
и ждали бы до тех пор, пока она не пройдет 30 секунд от точки отсчета.
stop
Наш таймер работает по этому же принципу. SDL запускает внутренний таймер в нашей программе, и мы можем получить время в миллисекундах используя SDL_GetTIcks(). Если вам нужно отмерить 1000 миллисекунд, вы сохраняете время когда вы начали ожидание и ждете до тех пор, пока разница между временем начала и текущем не будет равна 1000.

//Заголовки
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <string>
#include <sstream>

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

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;    
        }
    }

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

И, наконец, обновив экран продолжаем главный цикл.


Скачать исходники и материалы

Время: Один комментарий

Добавить комментарий