Таймер обратного отсчета не работает

Таймер обратного отсчета, который я создал, не работает. Интересно, что если я использую console.log для печати значения count, которое начинается с 3, печатается что-то наподобие -3498, даже если я включаю только около 15 секунд, так что должно быть что-то не так с установленным интервалом код. Значение отображается (если число больше 0), но установленный интервал изменяется слишком быстро.

Вот код

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);
}

Любая помощь будет оценена.

2 ответа

Решение

Мне немного неясно, чего вы пытаетесь достичь, но вот пример:

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
}

Насколько я могу судить, вам не нужен интервал.

Значение отображается, но изменяется слишком быстро

Вам нужно будет различать логику и представление. Когда countdown функция вызывается, вы планируете функцию, чтобы уменьшить количество в 1 с, и в то же время вы планируете countdown быть вызванным снова как можно быстрее. Интервал обновления холстов составляет около 16 мс... Это означает, что count уменьшается с такой скоростью, задерживается только через 1 секунду после запуска.

И это еще хуже, так как вы использовали setInterval который навсегда повторяет уменьшение countв то время как этот процесс запускается каждый кадр анимации...

Решение не использовать setTimeout/setInterval совсем. Они ненадежны и не должны использоваться для измерения времени. Вместо этого получите точные временные метки от Date объект (каждый раз, когда они вам нужны, т.е. каждый кадр анимации):

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();
Другие вопросы по тегам