如何降低Winforms计时器的滴答率?

时间:2018-12-05 11:22:07

标签: c# winforms

我正在编写一个简单的游戏,其中使用计时器来制作动画。计时器速率最初设置为200,但是每获得1000分,我希望计时器变得更快,所以我想我可以缩短间隔时间

if (score > 0 && score % 1000 == 0)
     {
         GameTimer.Interval -= 20;
     }

但是当我的得分达到1000时,winform在上面给出的行上崩溃并出现以下错误:

  

System.ArgumentOutOfRangeException:'值'0'对于时间间隔不是有效值。间隔必须大于0。   参数名称:间隔

如何正确降低间隔率? (或通过其他任何方式使我的程序运行速度更快)

编辑:上面给出的代码段放置在tick事件中,这导致if语句执行多次

3 个答案:

答案 0 :(得分:4)

该错误表明时间间隔值已达到零。

因此这些行将执行多次,直到崩溃:

 if (score > 0 && score % 1000 == 0)
 {
     GameTimer.Interval -= 20;
 }

那是因为在计时器一次通过条件后,每个间隔都满足条件。

在计时器代码之外定义逻辑,您会没事的:

 void Score(int value){

      score += value;
      if (score <= 0) return;

      if(score % 1000 == 0)
      {
          GameTimer.Interval -= 20;
          //if(GameTimer.Interval <= 0) I suppose level is already finished...
      }
 }

编辑

mjwills指出了这个问题,间隔仍然可能达到零。因此,您必须以消除这种风险的方式编写代码。

在这种情况下,非线性归约法更有意义:

 void Score(int value){

      score += value;
      if (score <= 0) return;

      if(score % 1000 == 0)
      {
          GameTimer.Interval *= .9f;
          if(GameTimer.Interval <= 0) GameTimer.Interval = 1;
      }
 }

答案 1 :(得分:2)

滴答速度不能小于或等于0。

您可以简单地添加一个if语句来检查:

if (GameTimer.Interval <= 20) {
    GameTimer.Interval = 1;
} else {
    GameTimer.Interval -= 20;
}

但是,这意味着计时器间隔将在达到一定分数后达到极限。另外,屏幕无法快速更新(每秒更新1000次)。您可能应该将帧速率保持在30fps。

因此,要使动画显示更快,请每秒处理更大比例的动画。例如,要将某物向右移动1000个像素,请勿每1/1000秒将其移动1个像素。而是每隔1/20秒将其移动50个像素。

根据您的评论:

  

问题是我不明白为什么间隔会低于零,if语句仅执行一次,并且立即给我该错误。

然后,您将多次执行if语句。我的猜测是您正在计时器刻度事件处理程序中运行它。一旦您的分数达到1000的倍数,该if语句将在每次计时器计时时运行,直到分数改变。

要解决此问题,您可以将代码放入比分的设置器中。

答案 2 :(得分:1)

计时器间隔不断减小,直到达到零“ 0”为止

您可以使用

int x = (score/1000)*20  
if (x < 200)
    GameTimer.Interval = (200 - x);