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

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

编辑

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

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

因此,如果您将速度因子设置为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; } } 

对它进行子类化,调用超类方法来完成它们的正常工作,但是将所有返回值乘以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; 

根据现代物理学 ,你需要做的是让你的计时器“更快”,就是加速运行软件的计算机。 我不是说它执行计算的速度,而是物理速度。 你得到的光速(常数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()来完成你想要的。