简体   繁体   English

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

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

Ideally I would like to have something similar to the Stopwatch class but with an extra property called Speed which would determine how quickly the timer changes minutes. 理想情况下,我希望有类似于秒表类的东西,但有一个名为Speed的额外属性,它将决定计时器改变分钟的速度。 I am not quite sure how I would go about implementing this. 我不太确定如何实现这一点。

Edit 编辑

Since people don't quite seem to understand why I want to do this. 因为人们似乎不太明白我为什么要这样做。 Consider playing a soccer game, or any sport game. 考虑玩足球比赛或任何体育比赛。 The halfs are measured in minutes, but the time-frame in which the game is played is significantly lower ie a 45 minute half is played in about 2.5 minutes. 半分是以分钟为单位测量的,但是比赛的时间范围显着降低,即在约2.5分钟内播放45分钟的一半。

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

I would use the Stopwatch as it is, then just multiply the result, for example: 我会按原样使用秒表 ,然后将结果相乘,例如:

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;

The reason your simple "multiplication" doesn't work is that it doesn't speeding up the passing of time - the factor applies to all time that has passed , as well as time that is passing . 你的简单“乘法”不起作用的原因是它不会加速时间的流逝 - 这个因素适用于所有已经过去的时间,以及经过的时间。

So, if you set your speed factor to 3 and then wait 10 minutes, your clock will correctly read 30 minutes. 因此,如果您将速度因子设置为3然后等待10分钟,那么您的时钟将正确读取30分钟。 But if you then change the factor to 2 , your clock will immediately read 20 minutes because the multiplication is applied to time already passed. 但是,如果您随后将因子更改为2 ,则您的时钟将立即读取20分钟,因为乘法应用于已经过去的时间。 That's obviously not correct. 这显然不正确。

I don't think the stopwatch is the class you want to measure "system time" with. 我不认为秒表是你想用“系统时间”测量的类。 I think you want to measure it yoruself, and store elapsed time in your own variable. 我想你想测量它yoruself,并将经过的时间存储在你自己的变量中。

Assuming that your target project really is a game, you will likely have your "game loop" somewhere in code. 假设您的目标项目确实是一个游戏,您可能会在代码中的某个地方进行“游戏循环”。 Each time through the loop, you can use a regular stopwatch object to measure how much real-time has elapsed. 每次循环时,您都可以使用常规秒表对象来测量实际经过的时间。 Multiply that value by your speed-up factor and add it to a separate game-time counter. 将该值乘以您的加速因子并将其添加到单独的游戏时间计数器。 That way, if you reduce your speed factor, you only reduce the factor applied to passing time, not to the time you've already recorded. 这样,如果减少速度因子,则只减少应用于传递时间的因子,而不是减少已经记录的时间。

You can wrap all this behaviour into your own stopwatch class if needs be. 如果需要,您可以将所有这些行为包装到您自己的秒表类中。 If you do that, then I'd suggest that you calculate/accumulate the elapsed time both "every time it's requested" and also "every time the factor is changed." 如果你这样做,那么我建议你计算/累计“每次请求时”和“每次因素改变时”的经过时间。 So you have a class something like this (note that I've skipped field declarations and some simple private methods for brevity - this is just a rough idea): 所以你有一个这样的类(注意我已经跳过了字段声明和一些简单的私有方法以简洁 - 这只是一个粗略的想法):

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

According to modern physics , what you need to do to make your timer go "faster" is to speed up the computer that your software is running one. 根据现代物理学 ,您需要做的是让计时器“更快”,这样可以加速运行软件的计算机。 I don't mean the speed at wich it performs calculations, but the physical speed. 我不是说它执行计算的速度,而是物理速度。 The close you get to the speed of light ( the constant C ) the greater the rate at which time passes for your computer, so as you approach the speed of light, time will "speed up" for you. 你得到的光速(常数C)越接近你的计算机的速度越大,所以当你接近光速时,时间将“加速”为你。

It sounds like what you might actually be looking for is an event scheduler, where you specify that certain events must happen at specific points in simulated time and you want to be able to change the relationship between real time and simulated time (perhaps dynamically). 听起来你实际上正在寻找的是一个事件调度程序,你可以在其中指定某些事件必须在模拟时间内的特定点发生,并且你希望能够改变实时和模拟时间之间的关系(可能是动态的)。 You can run into boundary cases when you start to change the speed of time in the process of running your simulation and you may also have to deal with cases where real time takes longer to return than normal (your thread didn't get a time slice as soon as you wanted, so you might not actually be able to achieve the simulated time you're targeting.) 当您在运行模拟过程中开始更改时间速度时,您可能会遇到边界情况,您可能还需要处理实际需要更长时间才能返回的情况(您的线程没有获得时间片)只要您愿意,您实际上可能无法实现您定位的模拟时间。)

For instance, suppose you wanted to update your simulation at least once per 50ms of simulated time. 例如,假设您希望每50毫秒模拟时间至少更新一次模拟。 You can implement the simulation scheduler as a queue where you push events and use a scaled output from a normal Stopwatch class to drive the scheduler. 您可以将模拟调度程序实现为一个队列,您可以在其中推送事件并使用正常Stopwatch类的缩放输出来驱动调度程序。 The process looks something like this: 该过程看起来像这样:

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

This can be generalized to different types of events occurring at different intervals. 这可以推广到以不同间隔发生的不同类型的事件。 You still need to deal with the boundary case where the event queue is ballooning because the simulation can't keep up with real time. 您仍然需要处理事件队列膨胀的边界情况,因为模拟无法跟上实时。

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

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

相关问题 我将如何处理? 不同项目沟通? C# - How would I go about this? Different projects communicating? C# 我将如何实现基于事件的异步模式? - How would I go about implementing the event-based asynchronous pattern? 我将如何在C#中实现Java代码,反之亦然? - How would I go about implementing java code in c# and vice versa? 我该如何进行单元测试呢? - How would I go about unit testing this? 我将如何强制EF每次都创建新的查询命令,或者我将如何实施拦截器来实现行级限制? - How would i force EF to create new query commands every time or Or how would I go about implementing an interceptor to achieve row level restrictions? 我将如何以编程方式捕获内部音频? - How would I go about programmatically capturing internal audio? 我如何将此方法从Winforms转换为WPF? - How would I go about translating this method from Winforms to WPF? 我将如何制作凯撒密码解密器? - How would I go about making a caesar cypher decrypter? 如何使用此查询选择更多列 - How would I go about selecting more columns with this query 如何在具有压力敏感度的绘画程序中进行绘图? - How would I go about drawing in a paint program with pressure sensitivity?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM