2010-04-04 6 views
2

Je crée un temporisateur général qui dispose d'une fonctionnalité permettant de compter à partir de 0 ou de décompter à partir d'un certain nombre. Je veux aussi que l'utilisateur puisse ajouter et soustraire du temps. Tout est simple à implémenter sauf dans le cas où le compte à rebours décompte à partir d'un certain nombre, et l'utilisateur ajoute ou soustrait de l'heure à partir de ce nombre.Algorithme pour le compte à rebours pouvant être ajouté à l'heure

Par exemple: (m_clock est une instance de l'horloge de SFML) Pour être un peu plus clair

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

, imaginez que la minuterie commence à 100 décompter. Après 10 secondes, la fonction ci-dessus ressemblerait à 100 -= 100 - 100 + 10, ce qui équivaut à 90. S'il était appelé après 20 secondes supplémentaires, cela ressemblerait à 90 -= 90 - 100 + 30, ce qui équivaut à 70.

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

Je sais que je peux le faire en utilisant plus de membres et en gardant la trace des temps précédents, etc. mais je me demande s'il me manque une implémentation qui est extrêmement évidente. Je préférerais le garder aussi simple que possible dans cette seule opération.

Répondre

3

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 espérons AddTime() ne fonctionne pas: m_elapsedTime est remplacé à chaque appel à GetElapsedTime(). La solution la plus simple est la voie ajoutée/soustraite du temps séparément et réusinage GetElapsedTime() ainsi:

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

Gah. même réponse que moi :-( – Yuliy

+0

Eh bien mon objectif était de ne pas avoir à utiliser un autre membre pour la fonctionnalité.Si c'était le cas, alors votre premier bloc ne fonctionnerait pas car l'ajout de temps directement à m_elapsedTime nécessiterait cette fonction à utiliser + = et - = Cependant, si la création d'un membre séparé est la seule option, alors c'est ce que je vais faire – Person

+1

Ce n'est pas un membre supplémentaire Vous vous débarrassez de m_elapsedTime, et en ajoutant m_addedTime – Yuliy

1

Si vous voulez augmenter le temps restant, vous pouvez simuler cela en diminuant la quantité de temps écoulé.

Vos expressions arithmétiques sont plus complexes qu'ils doivent être: m_elapsedTime += m_clock.GetElapsedTime() - m_elapsedTime est équivalent à m_elapsedTime = m_clock.GetElapsedTime() et m_elapsedTime -= m_elapsedTime - m_startingTime + m_clock.GetElapsedTime() est équivalent à m_elapsedTime = m_startingTime - m_clock.GetElapsedTime() `. À ce stade, le problème est clair: l'ancienne valeur de m_elapsedTime n'affecte jamais le résultat suivant. Je envisagerais d'ajouter dans un champ offset pour gérer les modifications apportées à la valeur de départ de la minuterie. À ce stade, la minuterie: GetElapsedTime pourrait juste être les suivantes:

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 de regarder vos signes pour mettre à jour le décalage dans AddTime()

+0

Je l'ai dit plus haut, si vous utilisez AddTime directement sur m_elapsedTime, vous devez utiliser + = et - = pour la fonction GetElapsedTime, mais l'implémentation d'un membre séparé semble être la solution. – Person