Выполнить код после загрузки всех картинок

Делаю простую 2d игрушку на js. Имеется массив спрайтов(массив объектов класса Sprite(Sprite наследуется от Image и есть возможность посмотреть поле complete и вызвать событие onload)), хочу чтобы выполнение цикла игры начиналось после загрузки всех спрайтов. Как можно это сделать? Было много костыльных идей, но никак не могу понять как ето можно нормально реализовать.


Ответы (2 шт):

Автор решения: OPTIMUS PRIME

Можно завести счетчик, взять массив картинок, начать циклом их загружать и при каждой загрузке считать +1. Когда счетчик дойдет до размера массива, значит всё загрузилось, можно запускать игру:

onload_sprites(start_game);

function onload_sprites(callback) {
  let sprites = [
    "https://picsum.photos/200/300",
    "https://picsum.photos/200/300",
    "https://picsum.photos/200/300",
    "https://picsum.photos/200/300",
    "https://picsum.photos/200/300",
  ];
  
  let sprites_loaded = 0;
  
  sprites.forEach(function(sprite) {
    let img = new Image();
    img.onload = function() {
      sprites_loaded++;
      call();
    };
    
    img.onerror = function() {
      sprites_loaded++;
      console.log(sprite, "не загрузился!");
      call();
    }
    img.src = sprite;
  });
  
  function call() {
    if( sprites_loaded === sprites.length ) {
      callback();
    }
  }
}

function start_game() {
  console.log("Начали!");
}

→ Ссылка
Автор решения: Давид Манжула

Используйте Promise.all

let sprites = [
  "https://picsum.photos/200/300",
  "https://picsum.photos/200/300",
  "https://picsum.photos/200/300",
  "https://picsum.photos/200/300",
  "https://picsum.photos/200/300",
];

(async () => {

  const allResources = await Promise.all(sprites.map(url => fetch(url)));
  console.log(allResources);

})();

→ Ссылка