Пытаться понять контекст на холсте концепции - PullRequest
1 голос
/ 21 апреля 2020

Написание одной из тех простых игр для изучения js. Обучение html5 в процессе, поэтому мне нужно рисовать вещи на холсте.

Вот код:

 let paddle = new Paddle(GAME_WIDTH,GAME_HEIGHT);

 new InputHandler(paddle);

 let lastTime = 0;

 const ball = new Image();
 ball.src = 'assets/ball.png';

 function gameLoop(timeStamp){
   let dt = timeStamp - lastTime;
   lastTime = timeStamp;

   ctx.clearRect(0,0,600,600);
   paddle.update(dt);
   paddle.draw(ctx);

   ball.onload = () => {
    ctx.drawImage(ball,20,20);
  }

  window.requestAnimationFrame(gameLoop);
 }

gameLoop();

снимок экрана: без мяча до комментария

теперь я закомментирую clearRect ():

после комментария

привет мяч.

Там также есть весло в нижней части холст, на который, похоже, не влияет метод clearRect (). Работает просто отлично. Что мне здесь не хватает?

1 Ответ

1 голос
/ 21 апреля 2020

Нет смысла помещать обработчик onload изображения в игру l oop. Это означает, что игра должна начаться до того, как будет установлена ​​функция onload изображения, что приведет к довольно запутанной ситуации.

Правильная последовательность - установить обработчики onload, затем источники изображения, затем await все изображения onload стреляют перед запуском игры l oop. Установить основной l oop на onload напрямую довольно легко, если у вас есть только одно изображение, но для игры с несколькими активами это может быстро стать неловким.

Вот минимальный пример того, как вы может загрузить множество игровых ресурсов, используя Promise.all. Очень вероятно, что вы захотите распаковать загруженные изображения в более описательные объекты, а не в массив, но это только начало.

const canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = 400;
canvas.height = 250;
const ctx = canvas.getContext("2d");

const assets = ["http://www.placekitten.com/120/100",
                "http://www.placekitten.com/120/120",
                "http://www.placekitten.com/120/140"];
const assetsLoaded = assets.map(url =>  
  new Promise(resolve => {
    const img = new Image();
    img.onload = function () {
      resolve(this);
    };
    img.src = url;
  })
);

(async () => {
  const images = await Promise.all(assetsLoaded);
  
  (function gameLoop() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    images.forEach((e, i) => 
      ctx.drawImage(e, i * 120, Math.sin(Date.now() * 0.005) * 20 + 40)
    );
    requestAnimationFrame(gameLoop);
  })();
})();
...