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

StackOverflow https://stackoverflow.com/questions/2576251

Вопрос

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

Например: (m_clock - это экземпляр часов SFML)

float Timer::GetElapsedTime() {
  if ( m_forward ) {
    m_elapsedTime += m_clock.GetElapsedTime() - m_elapsedTime;
  } else {
    m_elapsedTime -= 
      m_elapsedTime - m_startingTime + m_clock.GetElapsedTime();
  }
  return m_elapsedTime;
}

Чтобы быть немного более понятным, представьте, что таймер начинается с 100 отсчет. Через 10 секунд вышеупомянутая функция будет выглядеть 100 -= 100 - 100 + 10 который равняется 90. Отказ Если он был вызван через 20 секунд, это было бы выглядеть 90 -= 90 - 100 + 30 который равняется 70.

Это работает для нормального подсчета, но если пользователь звонит на добавление () (просто m_elapsedteTime + = arg), то алгоритм для подсчета обратного отсчета не работает несчастнее.

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

Это было полезно?

Решение

Ваш код излишне сложен. Ниже эквивалентно:

float Timer::GetElapsedTime() {
  if ( m_forward ) {
    m_elapsedTime = m_clock.GetElapsedTime();
  } else {
    m_elapsedTime = m_startingTime - m_clock.GetElapsedTime();
  }
  return m_elapsedTime;
}

и, надеюсь, иллюстрирует почему AddTime() не работает: m_elapsedTime заменяется на каждый звонок GetElapsedTime(). Отказ Самое простое решение - это добавленное / вычвенное время отдельно и переработка GetElapsedTime() таким образом:

float Timer::GetElapsedTime() {
  float elapsedTime = m_forward
                      ? m_clock.GetElapsedTime()
                      : m_startingTime - m_clock.GetElapsedTime();
  return elapsedTime + m_addedTime;
}

Другие советы

Если вы хотите увеличить оставшееся время, вы можете имитировать это уменьшение количество времени прошло.

Ваши арифметические выражения являются более сложными, чем они должны быть: m_elapsedTime += m_clock.GetElapsedTime() - m_elapsedTime эквивалентно m_elapsedTime = m_clock.GetElapsedTime(), а также m_elapsedTime -= m_elapsedTime - m_startingTime + m_clock.GetElapsedTime() эквивалентно M_ELAPSEDTEMETTE = M_STARTINGTETIONTION - M_CLOCK.GETELAPSEDTEMETTEME () `.

На данный момент проблема понятна: старое значение m_elapsedteime никогда не влияет на последующий результат. Я бы рассмотрел добавление в offset поле для обработки любых изменений в начальном величине таймера. На данный момент таймер: GetelapSedTime может быть просто следующим:

float Timer::GetElapsedTime() {
  if ( m_forward ) {
    return offset + m_clock.GetElapsedTime();
  } else {
    return offset - m_clock.GetElapsedTime();
  }
}

где смещение начинается с 0 для подсчета и начальное значение для подсчета. Убедитесь, что и посмотрите свои знаки для обновления компенсации в AddTime()

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top