繁体   English   中英

我将如何实施不同速度的秒表?

[英]How would I go about implementing a stopwatch with different speeds?

理想情况下,我希望有类似于秒表类的东西,但有一个名为Speed的额外属性,它将决定计时器改变分钟的速度。 我不太确定如何实现这一点。

编辑

因为人们似乎不太明白我为什么要这样做。 考虑玩足球比赛或任何体育比赛。 半分是以分钟为单位测量的,但是比赛的时间范围显着降低,即在约2.5分钟内播放45分钟的一半。

对它进行子类化,调用超类方法来完成它们的正常工作,但是将所有返回值乘以Speed。

我会按原样使用秒表 ,然后将结果相乘,例如:

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;

你的简单“乘法”不起作用的原因是它不会加速时间的流逝 - 这个因素适用于所有已经过去的时间,以及经过的时间。

因此,如果您将速度因子设置为3然后等待10分钟,那么您的时钟将正确读取30分钟。 但是,如果您随后将因子更改为2 ,则您的时钟将立即读取20分钟,因为乘法应用于已经过去的时间。 这显然不正确。

我不认为秒表是你想用“系统时间”测量的类。 我想你想测量它yoruself,并将经过的时间存储在你自己的变量中。

假设您的目标项目确实是一个游戏,您可能会在代码中的某个地方进行“游戏循环”。 每次循环时,您都可以使用常规秒表对象来测量实际经过的时间。 将该值乘以您的加速因子并将其添加到单独的游戏时间计数器。 这样,如果减少速度因子,则只减少应用于传递时间的因子,而不是减少已经记录的时间。

如果需要,您可以将所有这些行为包装到您自己的秒表类中。 如果你这样做,那么我建议你计算/累计“每次请求时”和“每次因素改变时”的经过时间。 所以你有一个这样的类(注意我已经跳过了字段声明和一些简单的私有方法以简洁 - 这只是一个粗略的想法):

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

根据现代物理学 ,您需要做的是让计时器“更快”,这样可以加速运行软件的计算机。 我不是说它执行计算的速度,而是物理速度。 你得到的光速(常数C)越接近你的计算机的速度越大,所以当你接近光速时,时间将“加速”为你。

听起来你实际上正在寻找的是一个事件调度程序,你可以在其中指定某些事件必须在模拟时间内的特定点发生,并且你希望能够改变实时和模拟时间之间的关系(可能是动态的)。 当您在运行模拟过程中开始更改时间速度时,您可能会遇到边界情况,您可能还需要处理实际需要更长时间才能返回的情况(您的线程没有获得时间片)只要您愿意,您实际上可能无法实现您定位的模拟时间。)

例如,假设您希望每50毫秒模拟时间至少更新一次模拟。 您可以将模拟调度程序实现为一个队列,您可以在其中推送事件并使用正常Stopwatch类的缩放输出来驱动调度程序。 该过程看起来像这样:

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

这可以推广到以不同间隔发生的不同类型的事件。 您仍然需要处理事件队列膨胀的边界情况,因为模拟无法跟上实时。

我不完全确定你要做什么(一分钟总是有60秒?),但我会利用Thread.Sleep()来完成你想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM