Обработка времени

Время в SFML

В отличии от большинства других библиотек, в которых время представлено в виде числа миллисекунд (тип данных uint32) или числа секунд (float), SFML не навязывает какие-либо специфические единицы или типы для значений времени. Вместо этого библиотека оставляет этот выбор за пользователем через гибкий класс sf::Time. Все классы и функции библиотеки SFML, работающие со временем, используют этот класс.

sf::Time определяет временной интервал. Иными словами, не представляет какое-то конкретное значение даты и времени (год/месяц/день/час/минута/секунда), а просто показывает количество времени, и то как оно будет истолковываться, зависит уже от контекста.

Преобразование времени

Значения sf::Time могут создаваться из различных единиц: секунды, миллисекунды и микросекунды. Существуют функции (не являющиеся членами класса) для превращения этих единиц в sf::Time:

sf::Time t1 = sf::microseconds(10000);
sf::Time t2 = sf::milliseconds(10);
sf::Time t3 = sf::seconds(0.01f);

Заметьте, все эти три значения времени одинаковые.

Кроме того, sf::Time можно преобразовать обратно в секунды, миллисекунды и микросекунды:

sf::Time time = ...;

sf::Int64 usec = time.asMicroseconds();
sf::Int32 msec = time.asMilliseconds();
float     sec  = time.asSeconds();

Работа со значениями времени

sf::Time это просто количество времени, поэтому к объектам этого класса применимы арифметические операции (сложение, вычитание, сравнение и т.п.). Они так же могут быть отрицательными.

sf::Time t1 = ...;
sf::Time t2 = t1 * 2;
sf::Time t3 = t1 + t2;
sf::Time t4 = -t3;

bool b1 = (t1 == t2);
bool b2 = (t3 > t4);

Измерение времени

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

SFML имеет простой класс для измерения времени sf::Clock. Он располагает только двумя функциями: getElapsedTime() возвращающей время, прошедшее с запуска часов, и restart() перезапускающей часы.

sf::Clock clock; // starts the clock
...
sf::Time elapsed1 = clock.getElapsedTime();
std::cout << elapsed1.asSeconds() << std::endl;
clock.restart();
...
sf::Time elapsed2 = clock.getElapsedTime();
std::cout << elapsed2.asSeconds() << std::endl;

Обратите внимание, что restart() так же возвращает прошедшее время, так что вы можете избежать возникновения небольшого временного зазора, который появится если вы вызовите getElapsedTime() сразу после restart().

Вот пример, который использует прошедшее время каждой итерации игрового цикла, что бы обновить игровую логику:

sf::Clock clock;
while (window.isOpen())
{
    sf::Time elapsed = clock.restart();
    updateGame(elapsed);
    ...
}

 

9 Комментарии

  1. Павел

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

  2. Павел

    Почему у меня не работает вот такая вещь:

    sf::Clock clock;
    
    			sf::Time elapsed1 = clock.getElapsedTime();
    			//std::cout << elapsed1.asMicroseconds() <= 10)
    			{
    				std::cout << elapsed1.asMicroseconds() << std::endl;
    				if(roadb == true)
    				{
    					window.draw(road2_s);
    					roadb = false;
    				}
    				else
    				{
    					window.draw(roads);
    					roadb = true;
    				}
    				clock.restart();
    			}
    

    что я сделал не правильно?

    1. samuel_unknown (Автор записи)

      Что именно не работает? Опиши что ты хочешь сделать..

  3. Павел

    Ну с этой проблемой я справился, но всё равно есть другая, мне нужно выполнить какое то действие по истечению определённого промежутка времени…как это сделать?

    1. samuel_unknown (Автор записи)

      Сделать можно примерно так:

      sf::Clock clock;
      
      // начинаем отсчёт таймера
      sf::Time elapsed = clock.restart();
      
      while (elapsed.asMicroseconds() < 100000) {
          
          // узнаём сколько прошло времени
          elapsed = clock.getElapsedTime();
          
          if (elapsed.asMicroseconds() < 30000)
              std::cout << событие 1: << std::endl;
      
          if ( (elapsed.asMicroseconds() > 30000) && (elapsed.asMicroseconds() < 60000) )
              std::cout << событие 2: << std::endl;
      
          if (elapsed.asMicroseconds() > 60000)
              std::cout < < событие 3: << std::endl;
      }
      
  4. Александр

    Спасибо за совет

  5. Саня

    Помогите. Как сделать таймер чтобы через времени началась какое-то действие и потом таймер остановился. И да я попробовал тот код что выше но у мене почему-то из за цикл while перестает работать основной цикл и окно не работает.

  6. Саньок

    Как мне сделать таймер для вывода текста на екран. Пример выше останавливает саму игру на время а мне надо для действия. Как так сделать?

    1. Владимир

      Используй условия. Неужели это сложно. Хочешь создать алгоритм задержки вывода текста и лезешь на форум. Вот тебе.

      лог_переменная = лож;
      если (лог_переменная) рисуешь текст на экране ;
      если (время >= нужного) лог_переменная = истина;

      Всего 3 строки. Это на языке абстракции для понимания. Думаю разберешься.

Добавить комментарий для Саньок Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Капча * Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.