user2350334
user2350334

Reputation: 49

Countdown timer not working

The countdown timer I created doesn't work. Interestingly, if I use console.log to print the value of count--which starts at 3--something like -3498 is printed, even if I am only on for around 15 seconds, so there must be something wrong with the set interval code. The value is displayed(if count is greater than 0), but set interval changes too quickly.

Here's the code.

function countdown(){
  window_width=window.innerWidth-70;
  window_height=window.innerHeight-150;

  canvas = document.getElementById("gameCanvas");
  ctx=canvas.getContext("2d");
  canvas.width  = window_width;
  canvas.height=window_height;

  if(count>0){
    ctx.font = '40pt Calibri';
    ctx.fillStyle = "white";
    ctx.fillText(count, window_width/3, window_height/2);
  }
  else if(count===0){
    ctx.fillText("Go!", window_width/3, window_height/2);
  }
  else{
   return;
  }

  setInterval(function(){count=count-1},1000);
  requestAnimationFrame(countdown);
}

Any help would be appreciated.

Upvotes: 1

Views: 871

Answers (2)

Bergi
Bergi

Reputation: 664297

The value is displayed, but changes too quickly

You will need to distinguish between logic and presentation. When the countdown function is called, you schedule a function to decrease the count in 1s, and at the same time you schedule countdown to be called again as fast as possible. The update interval of canvases is about 16ms though… It means the count is decreased at that rate, only delayed 1 second after starting.

And it's even worse, as you did use setInterval which forever repeats decreasing the count, while that process is started every animation frame…

The solution is not to use setTimeout/setInterval at all. They are unreliable and should not be used for measuring the time. Instead, get accurate timestamps from the Date object (every time you need them, ie. every animation frame):

var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
canvas.width  = window.innerWidth -70;
canvas.height = window.innerHeight-150;
ctx.font = '40pt Calibri';
ctx.fillStyle = "white";

var count = …;

var estimatedEnd = Date.now() + count*1000;

function countdown(){
    var currentCount = (estimatedEnd - Date.now()) / 1000;

    if (currentCount>0){
        ctx.fillText(currentCount, window_width/3, window_height/2);
        requestAnimationFrame(countdown);
    } else if (currentCount===0){
        ctx.fillText("Go!", window_width/3, window_height/2);
    }
}
countdown();

Upvotes: 1

ic3b3rg
ic3b3rg

Reputation: 14927

I'm a bit unclear as to what you're trying to accomplish, but here's a shot at it:

window.count = 3;

setTimeout(countdown,1000);

function countdown(){
  window_width=window.innerWidth-70;
  window_height=window.innerHeight-150;

  canvas = document.getElementById("gameCanvas");
  ctx=canvas.getContext("2d");
  canvas.width  = window_width;
  canvas.height=window_height;

  count--;

  if(count>0){
    ctx.font = '40pt Calibri';
    ctx.fillStyle = "white";
    ctx.fillText(count, window_width/3, window_height/2);
    setTimeout(countdown,1000);
  }
  else if(count===0){
    ctx.fillText("Go!", window_width/3, window_height/2);
  }
  else{
   return;
  }

  requestAnimationFrame(countdown); // not sure if this is needed
}

As far as I can tell, you don't need the interval.

Upvotes: 1

Related Questions