2010-05-18 24 views
4

Idéalement, je voudrais avoir quelque chose de similaire à la classe Stopwatch, mais avec une propriété supplémentaire appelée Speed qui permettrait de déterminer à quelle vitesse le minuteur change minutes. Je ne suis pas tout à fait sûr de la façon dont j'allais mettre en œuvre ceci.Comment procéder pour mettre en place un chronomètre à différentes vitesses?

Modifier

Puisque les gens ne semblent tout à fait comprendre pourquoi je veux faire. Envisagez de jouer à un jeu de football ou à un jeu de sport. Les demi-mesures sont mesurées en minutes, mais le temps dans lequel le jeu est joué est significativement plus faible, c'est-à-dire qu'une demi-heure de 45 minutes est jouée en environ 2,5 minutes.

+3

Je dois manquer quelque chose ... le chronomètre change les minutes toutes les minutes. Si vous cherchez à ralentir le temps, je regarderais ailleurs. –

+0

Vous voulez un chronomètre qui se trouve sur combien de temps une période s'est écoulée? Pourquoi ne pas simplement multiplier sa valeur par un facteur après avoir mesuré? –

+0

... lol @justin ... –

Répondre

2

La raison pour laquelle votre « multiplication » simple ne fonctionne pas est que cela n'accélère pas le passage du temps - le facteur applique à tous les temps qui a passé , ainsi que le temps qui passe .

Donc, si vous définissez votre facteur de vitesse à 3 puis attendez 10 minutes, votre horloge lu 30 minutes correctement. Mais si vous changez ensuite le facteur en 2, votre horloge lira immédiatement 20 minutes car la multiplication est appliquée au temps déjà passé. Ce n'est évidemment pas correct.

Je ne pense pas que le chronomètre est la classe que vous voulez mesurer le « temps du système » avec. Je pense que vous voulez le mesurer et stocker le temps écoulé dans votre propre variable.

Si l'on suppose que votre projet cible est vraiment un jeu, vous aurez probablement votre « boucle de jeu » quelque part dans le code. Chaque fois que vous parcourez la boucle, vous pouvez utiliser un objet chronomètre régulier pour mesurer combien de temps réel s'est écoulé. Multipliez cette valeur par votre facteur d'accélération et ajoutez-la à un compteur de temps de jeu séparé. De cette façon, si vous réduisez votre facteur de vitesse, vous réduisez uniquement le facteur appliqué à en passant le temps, et non le temps que vous avez déjà enregistré.

Vous pouvez envelopper tout ce comportement dans votre propre classe chronomètre si besoin est. Si vous faites cela, alors je vous suggère de calculer/accumuler le temps écoulé à la fois "chaque fois que c'est demandé" et aussi "chaque fois que le facteur est changé.«Vous avez donc une chose de classe comme ceci (notez que j'ai des déclarations sur le terrain sautées et des méthodes privées simples par souci de brièveté - c'est juste une idée approximative):

public class SpeedyStopwatch 
{ 
    // This is the time that your game/system will run from 
    public TimeSpan ElapsedTime 
    { 
     get 
     { 
      CalculateElapsedTime(); 
      return this._elapsedTime; 
     } 
    } 

    // This can be set to any value to control the passage of time 
    public double ElapsedTime 
    { 
     get { return this._timeFactor; } 
     set 
     { 
      CalculateElapsedTime(); 
      this._timeFactor = value; 
     } 
    } 

    private void CalculateElapsedTime() 
    { 
     // Find out how long (real-time) since we last called the method 
     TimeSpan lastTimeInterval = GetElapsedTimeSinceLastCalculation(); 

     // Multiply this time by our factor 
     lastTimeInterval *= this._timeFactor; 

     // Add the multiplied time to our elapsed time 
     this._elapsedTime += lastTimeInterval; 
    } 
} 
+0

C'était un peu ce que je soupçonnais d'avoir à faire tous les calculs manuellement. Je pensais juste qu'il aurait pu y avoir un moyen plus facile d'utiliser quelque chose comme la classe Stopwatch. – James

-2

Je ne suis pas tout à fait sûr de ce que vous cherchez à faire (ne pas une minute toujours 60 secondes?), Mais je Thread.Sleep utilisent() pour accomplir ce que vous voulez.

7

sous-classer, par appel aux méthodes de superclasse pour faire leur travail habituel, mais multiplier toutes les valeurs de retour par la vitesse selon le cas.

+0

Je faisais quelque chose de similaire mais le calcul des minutes ne fonctionnait pas correctement si je changeais la vitesse pendant l'exécution. – James

+0

Lorsque vous modifiez la vitesse, calculez le temps jusqu'à la fin et réinitialisez la minuterie interne. Lorsque vous voulez lire l'heure, multipliez le dernier intervalle par la vitesse et ajoutez ce temps-là. –

+0

@Hans: Pourriez-vous poster une réponse avec un exemple? – James

3

J'utiliseraient le Stopwatch comme il est, alors il suffit de multiplier le résultat, par exemple:

var Speed = 1.2; //Time progresses 20% faster in this example 
var s = new Stopwatch(); 
s.Start(); 
    //do things 
s.Stop(); 
var parallelUniverseMilliseconds = s.ElapsedMilliseconds * Speed; 
0

Selon modern physics, ce que vous devez faire pour rendre votre minuterie aller « plus vite » est d'accélérer l'ordinateur sur lequel votre logiciel est en cours d'exécution. Je ne parle pas de la vitesse à laquelle il effectue les calculs, mais de la vitesse physique. Plus vous approchez de la vitesse de la lumière (la constante C) plus la vitesse à laquelle votre ordinateur passe est longue, plus vous approchez de la vitesse de la lumière, plus le temps "accélère" pour vous.

+0

Que voulez-vous dire par "physique moderne"? Ont-ils changé récemment? :) –

+0

lol post Albert Einstein –

+0

Cela provoquerait une lenteur de l'horloge de l'ordinateur telle que perçue par l'observateur. Toi, pas l'ordinateur, tu devrais aller plus vite d'une marge considérable. –

0

Il ressemble à ce que vous pourriez vraiment être à la recherche pour est un planificateur d'événements, où vous spécifiez que certains événements doivent se produire à des moments précis dans un temps simulé et que vous voulez pouvoir modifier la relation entre le temps réel et le temps simulé (peut-être dynamiquement). pour changer la vitesse du temps dans le processus de votre simulation et vous pouvez également avoir à faire face à des cas où le temps réel prend plus de temps à revenir que normal (votre thread n'a pas eu une tranche de temps aussi vite que vous le vouliez pas réellement être en mesure d'atteindre l'heure simulée que vous ciblez.)Par exemple, supposons que vous vouliez mettre à jour votre simulation au moins une fois par 50 ms de temps simulé. Vous pouvez implémenter le planificateur de simulation en tant que file d'attente dans laquelle vous importez des événements et utilisez une sortie mise à l'échelle d'une classe Stopwatch normale pour piloter le planificateur. Le processus ressemble à ceci:

Push (simulate at t=0) event to event queue 
Start stopwatch 
lastTime = 0 
simTime = 0 
While running 
    simTime += scale*(stopwatch.Time - lastTime) 
    lastTime = stopwatch.Time 
    While events in queue that have past their time 
     pop and execute event 
     push (simulate at t=lastEventT + dt) event to event queue 

Ceci peut être généralisé à différents types d'événements qui se produisent à des intervalles différents. Vous devez toujours gérer le cas limite dans lequel la file d'attente d'événements gonfle car la simulation ne peut pas suivre en temps réel.