Как мне поставить таймер, который считает в HTML5 Canvas с Javascript? - PullRequest
0 голосов
/ 11 декабря 2019

Я создал платформерную игру со спрайт-персонажем. Я хочу иметь возможность иметь таймер где-то в верхнем левом углу, который отсчитывает каждую секунду (00:00, 00:01).

Я уже делал таймер раньше, но он был отсчитан, и это не так, потому что я использую requestAnimationframe для своего игрового цикла. Был бы признателен за несколько советов о том, как это сделать.

Я сделал счетчик смерти, уже используя этот код:

ctx.font = "20px Arial";
ctx.fillStyle = "white";
ctx.fillText("Deaths: " + deaths, 50, 50);

со смертельными случаями ++ в функции, которая сбрасывает положениеигрок. Однако я не могу понять, как поступить.

Вот jsFiddle моей игры (возможно, вам придется уменьшить масштаб, игра 1300x600. Стрелки для управления персонажем.):

https://jsfiddle.net/z3orewvb/

Ответы [ 2 ]

0 голосов
/ 12 декабря 2019

Строго говоря, вы можете использовать таймер в вашем loop(), поэтому он больше связан с игровой логикой и рендерингом. Просто сохраните время начала снаружи, и всякий раз, когда вы перерисовываете, вычисляете разницу:

let start=Date.now();
function reset() {
  start=Date.now();
}
let x=0,y=0,dx=0,dy=0;
function loop() {
  let seconds=Math.floor((Date.now()-start)/1000);
  let minutes=Math.floor(seconds/60);
  seconds%=60;
  dx+=x<cnv.width/2?1:-1;
  dy+=y<cnv.height/2?1:-1;
  x+=dx;
  y+=dy;
  let ctx=cnv.getContext("2d");
  ctx.fillStyle="#8080FF";
  ctx.beginPath();
  ctx.arc(x,y,10,0,Math.PI*2);
  ctx.fill();
  ctx.stroke();
  ctx.clearRect(0,0,30,15);
  ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,10);
  requestAnimationFrame(loop);
}
loop();
<button onclick="reset()">Reset</button><br>
<canvas id="cnv"></canvas>

Конечно, есть универсальный повторяющийся таймер, setInterval(). Но тогда у вас могут быть артефакты, если в том же месте нарисовано что-то еще:

let x=0,y=0,dx=0,dy=0;
function loop() {
  dx+=x<cnv.width/2?1:-1;
  dy+=y<cnv.height/2?1:-1;
  x+=dx;
  y+=dy;
  let ctx=cnv.getContext("2d");
  ctx.fillStyle="#8080FF";
  ctx.beginPath();
  ctx.arc(x,y,10,0,Math.PI*2);
  ctx.fill();
  ctx.stroke();
  requestAnimationFrame(loop);
}
loop();

let start=Date.now();
let counter=0;
function reset() {
  start=Date.now();
  counter=0;
}
setInterval(()=>{
  let ctx=cnv.getContext("2d");
  ctx.clearRect(0,0,30,25);
  let seconds=Math.floor((Date.now()-start)/1000);
  let minutes=Math.floor(seconds/60);
  seconds%=60;
  ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,10);
  counter++;
  minutes=Math.floor(counter/60);
  seconds=counter%60;
  ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,20);
},1000);
function problem() {
  let wait=Date.now()+1500;
  while(Date.now()<wait);
}
<button onclick="reset()">Reset</button><button onclick="problem()">Problem</button><br>
<canvas id="cnv"></canvas>

Также была добавлена ​​кнопка «Проблема» (нажмите ее пару раз): setInterval() делает все возможное, но она не пуленепробиваемая, онане компенсирует пропущенные / пропущенные расписания, эта секунда просто не произошла для setInterval() счетчика (нижний).

0 голосов
/ 11 декабря 2019

Вы должны быть в состоянии сделать что-то подобное. В функции обратного вызова я передаю обратно объект interval, чтобы при необходимости вы могли очистить интервал, чтобы он не продолжал работать в фоновом режиме. (или если вам нужно остановить счетчик в определенной точке) .. В этой демонстрации я остановил счетчик на 11 ..

function counter(callback) {
  var i = 0;
  let interval = setInterval(function() {
    callback(i, interval);
    i++;
  }, 1000);
}

counter((currentTime, intervalObject) => {
  if (currentTime === 11) {
    clearInterval(intervalObject);
  } else {
    const canvas = document.getElementById("canvas");
    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    const data = `



${currentTime}
`;const img = новое изображение ();const svg = новый BLOB-объект ([data], {type: "image / svg + xml; charset = utf-8"});const url = URL.createObjectURL (svg);img.onload = function () {ctx.drawImage (img, 0, 0);URL.revokeObjectURL (URL);};img.src = url;}});
<canvas id="canvas"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...