2010-04-04 5 views
2

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

Например: (m_clock является экземпляром 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.

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

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

ответ

3

Ваш код излишне сложный. Следующее эквивалентно:

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

Gah. тот же ответ, что и я :-( – Yuliy

+0

Ну, моя цель заключалась в том, чтобы не использовать другой элемент для этой функции. Если это так, то ваш первый блок не будет работать, потому что добавление времени непосредственно в m_elapsedTime потребует использования этой функции + = и - =. Однако если создание отдельного элемента является единственным вариантом, то это то, с чем я буду работать. – Person

+1

Это не дополнительный член. Вы избавляетесь от m_elapsedTime и добавляете в m_addedTime. – Yuliy

1

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

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

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

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

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

+0

То же, что и Я сказал выше, если вы используете AddTime непосредственно на m_elapsedTime, тогда вам нужно использовать + = и - = для функции GetElapsedTime. Однако реализация отдельного элемента кажется способным. – Person

 Смежные вопросы

  • Нет связанных вопросов^_^