Question

Je fais une minuterie générale qui a une fonctionnalité de compter de 0 ou compte à rebours à partir d'un certain nombre. Je veux également permettre à l'utilisateur d'ajouter et de réduire la durée. Tout est simple à mettre en œuvre, sauf pour le cas où la minuterie compte à rebours d'un certain nombre, et l'utilisateur ajoute ou soustrait le temps de celui-ci.

Par exemple: (m_clock est une instance de l'horloge de 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;
}

Pour être un peu plus clair, imaginez que la minuterie commence à 100 décompter. Au bout de 10 secondes, la fonction ci-dessus ressemblerait 100 -= 100 - 100 + 10 ce qui équivaut à 90. Si on l'appelait il s'occuper 20 secondes comme 90 -= 90 - 100 + 30 ce qui équivaut à 70.

Cela fonctionne pour le comptage normal, mais si l'utilisateur appelle AddTime () (juste m_elapsedTime + = arg), puis l'algorithme de comptage ascendante échoue lamentablement.

Je sais que je peux le faire en utilisant plus de membres et garder trace des précédents, etc., mais je me demande si je manque une mise en œuvre qui est extrêmement évidente. Je préfère le garder aussi simple que possible dans cette seule opération.

Était-ce utile?

La solution

Votre code est inutilement complexe. Ce qui suit est équivalent:

float Timer::GetElapsedTime() {
  if ( m_forward ) {
    m_elapsedTime = m_clock.GetElapsedTime();
  } else {
    m_elapsedTime = m_startingTime - m_clock.GetElapsedTime();
  }
  return m_elapsedTime;
}

et illustre pourquoi nous l'espérons AddTime() ne fonctionne pas: m_elapsedTime est remplacé à chaque appel à GetElapsedTime(). La solution la plus simple est la voie ajouté / soustrait le temps séparément et retravailler GetElapsedTime() ainsi:

float Timer::GetElapsedTime() {
  float elapsedTime = m_forward
                      ? m_clock.GetElapsedTime()
                      : m_startingTime - m_clock.GetElapsedTime();
  return elapsedTime + m_addedTime;
}

Autres conseils

Si vous voulez augmenter le temps restant, vous pouvez simuler que par diminution la quantité de temps écoulé.

Vos expressions arithmétiques sont plus complexes qu'ils doivent être:. m_elapsedTime += m_clock.GetElapsedTime() - m_elapsedTime équivaut à m_elapsedTime = m_clock.GetElapsedTime(), et m_elapsedTime -= m_elapsedTime - m_startingTime + m_clock.GetElapsedTime() équivaut à m_elapsedTime = m_startingTime - m_clock.GetElapsedTime () `

À ce stade, le problème est clair: l'ancienne valeur de m_elapsedTime affecte jamais le résultat suivant. J'envisager d'ajouter dans un champ offset pour gérer toute modification de la valeur de départ de la minuterie. À ce stade, la minuterie: GetElapsedTime pourrait juste être le suivant:

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

où décalage commence à 0 pour un décompte et la valeur de départ pour un compte à rebours. Assurez-vous et regarder vos signes pour la mise à jour de décalage dans AddTime()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top