4

理想情况下,我希望有一些类似于Stopwatch类的东西,但有一个额外的属性Speed,它可以确定计时器更改分钟的速度。我不太确定我将如何实施这一点。

编辑

因为人们似乎不太明白我为什么要这样做。考虑踢足球比赛或任何体育比赛。半场以分钟为单位,但比赛的时间范围要短得多,即 45 分钟的半场在大约 2.5 分钟内完成。

4

6 回答 6

7

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

于 2010-05-18T12:33:11.500 回答
3

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

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;
于 2010-05-18T12:34:39.737 回答
2

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

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

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

假设您的目标项目确实是一个游戏,您可能会在代码中的某处有您的“游戏循环”。每次通过循环,您都可以使用常规秒表对象来测量经过了多少实时。将该值乘以您的加速因子,并将其添加到单独的游戏时间计数器中​​。那样的话,如果你降低你的速度因素,你只会降低适用于经过时间的因素,而不是你已经记录的时间。

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

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;
    }
 }
于 2010-05-18T13:13:35.677 回答
0

根据现代物理学,要使计时器“更快”运行,您需要做的是加快运行您的软件的计算机的速度。我不是指它执行计算的速度,而是物理速度。您越接近光速(常数 C ),计算机的时间流逝速度就越大,因此当您接近光速时,时间会为您“加速”。

于 2010-05-18T12:45:29.273 回答
0

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

例如,假设您希望每 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

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

于 2010-05-18T13:40:08.633 回答
-2

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

于 2010-05-18T12:32:57.430 回答