2

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 カウントダウンで始まると想像してください。100 -= 100 - 100 + 1010 秒後、上記の関数はwhich equalsのようになり90ます。90 -= 90 - 100 + 30さらに 20 秒後に呼び出された場合は、 which 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();
  }
}

ここで、オフセットはカウントアップの場合は 0 から始まり、カウントダウンの場合は開始値です。でオフセットを更新するための兆候を確認してくださいAddTime()

于 2010-04-04T23:38:00.667 に答える