簡體   English   中英

createImageBitmap 僅在頁面重新加載后執行

[英]createImageBitmap only executing after page is reloaded

當我加載我的網頁時,createImageBitmap 行不運行並且我的承諾列表留空,但是當我重新加載頁面時,承諾在列表中,並且該列表似乎在調用 function 之前已填充. 這會導致問題並使我的游戲崩潰,因為承諾不會被解析為圖像。

為什么會發生這種情況,我該如何解決?

這是代碼的修改摘錄:

Spritesheets = {
    tileset_grass : new Image(),
    tileset : new Image(),
    player : new Image(),
    crawler : new Image(),
    creature : new Image(),
    items : new Image(),
    particles : new Image()
};
Spritesheets.tileset_grass.src = "images/tileset_grass.png";
Spritesheets.tileset.src = "images/tileset.png";
Spritesheets.player.src = "images/player.png";
Spritesheets.crawler.src = "images/crawler.png";
Spritesheets.creature.src = "images/creature.png";
Spritesheets.items.src = "images/items.png";
Spritesheets.particles.src = "images/particles.png";

// separates spritesheets into separate sprites
Images = {
    tileset_grass : {
        spriteW : 16,
        spriteH : 18
    },
    tileset : {
        spriteW : 16,
        spriteH : 16
    },
    player : {
        spriteW : 16,
        spriteH : 16
    },
    crawler : {
        spriteW : 16,
        spriteH : 16
    },
    creature : {
        spriteW : 16,
        spriteH : 16
    },
    items : {
        spriteW : 16,
        spriteH : 16
    },
    particles : {
        spriteW : 16,
        spriteH : 16
    },
};

console.log(Images)

function loadSprites() {
    for(let i = 0; i < Object.keys(Images).length; i++) {
        for(let k = 0; k < Spritesheets[Object.keys(Images)[i]].naturalWidth / Images[Object.keys(Images)[i]].spriteW; k++) {
            Images[Object.keys(Images)[i]][k] = createImageBitmap(Spritesheets[Object.keys(Images)[i]], k * Images[Object.keys(Images)[i]].spriteW, 0, Images[Object.keys(Images)[i]].spriteW, Images[Object.keys(Images)[i]].spriteH);
        };
    };
    console.log(Images)
};

loadSprites();

將 HTMLImageElement 作為createImageBitmap()的源傳遞時,該元素必須在解碼后的 state 中,即它的load事件必須已觸發。

它在您重新加載頁面時起作用,因為您很幸運,並且圖像從緩存中加載得足夠快。

因此,您可以在調用所有createImageBitmap()之前等待所有這些 HTMLImageElements 的load事件,或者您可以通過將所有資源作為 Blob 獲取並直接從這些 Blob 創建 ImageBitmap 來重構代碼以使其更快*,但是,您需要在 JS 中存儲圖像的大小以及裁剪選項。

Spritesheets = {
  tileset_grass : "images/tileset_grass.png",
  tileset : "images/tileset.png",
  player : "images/player.png",
  crawler : "images/crawler.png",
  creature : "images/creature.png",
  items : "images/items.png",
  particles : "images/particles.png"
};

// separates spritesheets into separate sprites
Images = {
  tileset_grass : {
    // add the image's width and height info here (or somewhere else)
    width: XXX,
    height: XXX,
    spriteW : 16,
    spriteH : 18
  }
};

async function loadSprites() {
  const keys = Object.keys(Images);
  for(let i = 0; i < keys.length; i++) {
    const key = keys[i];
    // fetch as Blob
    const blob = await fetch(Spritesheets[key]).then(resp => resp.ok && resp.blob());
    const img = Images[key];

    for(let k = 0; k < img.width / img.spriteW; k++) {
      img[k] = await createImageBitmap(blob, k * img.spriteW, 0, img.spriteW, img.spriteH);
    };
  };
  console.log(Images)
};
  • 它不一定會像執行更少的掛鍾時間那樣“更快”,但它將允許瀏覽器做更少的工作並並行優化其他任務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM