可增加时间的倒计时器算法
我正在制作一个通用计时器,它具有从 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 + 10
,等于 90
。如果再过 20 秒后调用它,它将类似于 90 -= 90 - 100 + 30
,等于 70
。
这适用于正常计数,但如果用户调用 AddTime() (只是 m_elapsedTime += arg ),则向后计数的算法会严重失败。
我知道我可以使用更多成员并跟踪以前的时间等来做到这一点,但我想知道我是否错过了一些非常明显的实现。我希望在单一操作中尽可能保持简单。
I'm making a general timer that has functionality to count up from 0 or count down from a certain number. I also want it to allow the user to add and subtract time. Everything is simple to implement except for the case in which the timer is counting down from some number, and the user adds or subtracts time from it.
For example: (m_clock is an instance of SFML's 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;
}
To be a bit more clear, imagine that the timer starts at 100 counting down. After 10 seconds, the above function would look like 100 -= 100 - 100 + 10
which equals 90
. If it was called after 20 more seconds it would look like 90 -= 90 - 100 + 30
which equals 70
.
This works for normal counting, but if the user calls AddTime() ( just m_elapsedTime += arg ) then the algorithm for backwards counting fails miserably.
I know that I can do this using more members and keeping track of previous times, etc. but I'm wondering whether I'm missing some implementation that is extremely obvious. I'd prefer to keep it as simple as possible in that single operation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的代码不必要地复杂。以下是等效的:
并希望说明为什么
AddTime()
不起作用:每次调用GetElapsedTime()
时都会替换m_elapsedTime
。最简单的解决方案是分别跟踪添加/减少的时间并重新修改GetElapsedTime()
因此:Your code is unnecessarily complex. The following is equivalent:
and hopefully illustrates why
AddTime()
doesn't work:m_elapsedTime
is being replaced on every call toGetElapsedTime()
. The simplest solution is track added/subtracted time separately and reworkGetElapsedTime()
thus:如果您想增加剩余时间,可以通过减少已用时间来模拟。
您的算术表达式比需要的更复杂:
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 可能如下:其中,向上计数的偏移量从 0 开始,向下计数的起始值。确保并观察
AddTime()
中更新偏移量的迹象If you want to increase the time remaining, you can simulate that by decreasing the amount of time elapsed.
Your arithmetic expressions are more complex than they need to be:
m_elapsedTime += m_clock.GetElapsedTime() - m_elapsedTime
is equivalent tom_elapsedTime = m_clock.GetElapsedTime()
, andm_elapsedTime -= m_elapsedTime - m_startingTime + m_clock.GetElapsedTime()
is equivalent to m_elapsedTime = m_startingTime - m_clock.GetElapsedTime()`.At this point, the problem is clear: the old value of m_elapsedTime never affects the subsequent result. I would consider adding in an
offset
field to handle any changes to the starting value of the timer. At this point, Timer:GetElapsedTime could just be the following:where offset starts at 0 for a count-up and the start value for a count-down. Make sure and watch your signs for updating offset in
AddTime()