Нет смысла помещать обработчик 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);
})();
})();