2

我正在制作一个通用计时器,它具有从 0 向上计数或从某个数字向下计数的功能。我还希望它允许用户增加和减少时间。一切都很容易实现,除了计时器从某个数字开始倒计时,并且用户从中添加或减去时间的情况。

例如:(m_clock 是 SFML 的 Clock 的一个实例)

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 + 10which equals 90。如果它在 20 秒后被调用,它看起来就像90 -= 90 - 100 + 30which equals 70

这适用于正常计数,但如果用户调用 AddTime() (只是 m_elapsedTime += arg ),则向后计数的算法会惨遭失败。

我知道我可以使用更多成员并跟踪以前的时间等来做到这一点,但我想知道我是否遗漏了一些非常明显的实现。我希望在单个操作中使其尽可能简单。

4

2 回答 2

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;
}
于 2010-04-04T23:35:29.267 回答
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字段来处理对计时器起始值的任何更改。此时, Timer:GetElapsedTime 可能只是以下内容:

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

其中 offset 从 0 开始向上计数,从起始值开始向下计数。确保并注意您的标志以更新偏移量AddTime()

于 2010-04-04T23:38:00.667 回答