【问题标题】:How would I go about implementing a stopwatch with different speeds?我将如何实施具有不同速度的秒表?
【发布时间】:2010-05-18 12:29:29
【问题描述】:

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

编辑

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

【问题讨论】:

  • 我一定遗漏了什么……秒表每分钟都会改变分钟。如果你想放慢时间,我会去别处看看。
  • 您想要一个秒表来显示一段时期已经过去了多长时间?为什么不在测量后将其值乘以一个因子?
  • @Justin:我想如果你没看错,你会看到我正在加快速度:)
  • @James 我想你最好找个二手的 Delorian...
  • @Justin:那将是理想的......如果我想回到过去

标签: c# timer stopwatch


【解决方案1】:

子类化它,调用超类的方法来完成它们的日常工作,但将所有返回值乘以适当的速度。

【讨论】:

  • 我正在做类似的事情,但如果我在整个执行过程中更改速度,分钟计算将无法正常工作。
  • 当你改变速度时,计算到目前为止的时间并重置内部计时器。当您想读取时间时,将最后一个时间间隔乘以速度,然后加上到目前为止的时间。
  • @Hans:你能举个例子吗?
  • @Andrew:乘以 what。蜱虫?毫秒?经过时间?
  • @James:假设您的规则是“每分钟 2 分钟实际分钟”。我会将ElapsedTicks 乘以 2。但是,这意味着 90 秒后将经过 3 分钟。如果您希望在 90 秒后经过 2 分钟,请乘以 (int)Elapsed.TotalMinutes。话虽如此,在这一点上,安德鲁和汉斯已经为您提供了足够多的信息来开始。与其现在寻求进一步的帮助,不如尝试自己实施。如果它不起作用,请寻求帮助。在这一点上,我觉得仅使用常识和思想就足以应用 Andrew 的解决方案。
【解决方案2】:

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

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】:

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

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

    【讨论】:

    • 这有点像我怀疑的,即必须手动进行所有计算。我只是认为使用类似 Stopwatch 类的东西可能有一种更简单的方法。
    【解决方案4】:

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

    【讨论】:

    • “现代物理学”是什么意思?他们最近有变化吗? :)
    • 这会导致观察者认为计算机时钟运行得更慢。您,而不是计算机,必须以相当大的幅度更快地移动。
    • 等一下……我的电脑更快了……我的工作更快了……!!这解释了我的质量增加!!!!哇靠。呼……妻子让我准备去健身房。被相对论拯救了……很酷。
    【解决方案5】:

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

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多