Алгоритм для ссчета таймера, который может добавить вовремя
Вопрос
Я делаю общий таймер, который имеет функциональность, чтобы подсчитываться от 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()