Ach113
Ach113

Reputation: 1825

How to reduce tick rate of winforms timer?

I am writing a simple game where animations are done using a timer. Timer rate is initially set to 200, but for every 1000 points player gets I want timer to get faster, so I thought I could just decrease the interval

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

But when I reach score of 1000, winform crashes with following error on the line given above:

System.ArgumentOutOfRangeException: 'Value '0' is not a valid value for Interval. Interval must be greater than 0. Parameter name: Interval

How can I correctly reduce the interval rate? (or make my program tick faster by any other means)

Edit: The code piece given above was placed inside the tick event, which caused if statement to execute several times

Upvotes: 0

Views: 1157

Answers (3)

Bizhan
Bizhan

Reputation: 17085

The error indicates that the Interval value has reached zero.

So these lines are executed several times until it crashes:

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

And that is because the condition is met in every interval after the timer passes the condition once.

Define your logic outside the timer code and you'll be fine:

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

edited

mjwills pointed out this issue that the interval still may hit zero. So you must write your code in a manner that eliminates this risk.

a non-linear reduction makes more sense in this case:

 void Score(int value){

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

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

Upvotes: 4

Ahmad Alkaraki
Ahmad Alkaraki

Reputation: 106

the timer interval keep decrease until it reach to zero "0" that is your error

you can use

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

Upvotes: 1

Sweeper
Sweeper

Reputation: 271735

The tick rate cannot be less than or equal to 0.

You could simply add an if statement to check that:

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

However, this means that the timer interval will reach a limit after a certain score is reached. Also, the screen can't update that fast (1000 times a second). You should probably keep the frame rate at 30fps.

Therefore, to make the animation appear faster, do a larger proportion of the animation in each second. For example, to move something 1000 pixels to the right, don't move it 1 pixel every 1/1000 of a second. Instead, move it 50 pixels every 1/20 of a second.

From your comment:

The issue is that I do not understand why interval is going below zero, the if statement is executed only once, and it immediately gives me that error.

Then you are executing the if statement more than once. My guess is that you are running it in the timer tick event handler. Once your score reaches a multiple of 1000, that if statement will be run every time the timer ticks, until your score changes.

To fix this, you can put the code in the setter of the score.

Upvotes: 2

Related Questions