【问题标题】:How to load/unload images in HTML5/JavaScript如何在 HTML5/JavaScript 中加载/卸载图像
【发布时间】:2019-03-10 23:11:47
【问题描述】:

我正在使用 HTML5 和 JavaScript 创建一个游戏,它将使用大量图像。同时拥有所有这些图像会占用大量内存,我想知道如何加载/卸载不同的图像,这样玩游戏的人就不需要 8GB 左右的内存来存储图像。

<img src = "source1" id = "img1"></img>
<img src = "source2" id = "img2"></img>
<img src = "source3" id = "img3"></img>
<!--Just imagine this for every image, which is likely going to peak over 10,000 at some point-->
<img src = "source10000" id = "img10000"></img>

<canvas width = "1350" height = "600" id = "canva"></canvas>
<script>
var canvas = document.getElementById("canva");
var can = canvas.getContext("2d");

var imge = function(im, x, y, w, h) {
can.drawImage(document.getElementById(im), x, y, w, h);
};

var playerX = 0;
var playerY = 0;

var run = function() {
imge("img1", playerX, playerY, 32, 32);
//Need to use tones of images
requestAnimationFrame(run);
};
run();

</script>

我不需要一次使用 10,000 张图像,更像是一次使用 60 张(玩家动画、方块、敌人动画、粒子等),而且由于我处于开发初期,因此我愿意接受重做一些东西,比如我如何抓取图像。

问题:如何在 HTML5/JavaScrpit 中加载/卸载图像

【问题讨论】:

  • 不要使用太多图像。最好用多个精灵创建更大的图像,并使用 CSS 背景定位对其进行动画处理。看看这里的例子:spriters-resource.com/snes/smarioworld/sheet/53664
  • 8GB 图片?你的游戏的生命周期是多久?如果你不做一个开放的世界,这听起来有点多。可能有一些你必须在那里检查的东西。
  • @Kaiido 说得太夸张了。我的游戏最多只需要 500MB。
  • 为什么要夸大?您处理 500MB 资产和 8GB 资产的方式不同......
  • 我的意思是使用了多少内存,而不是存储空间。如果我加载了 10,000 张图片而我只使用了其中的 60 张,那么我在 9,940 张未使用的图片上浪费了内存。

标签: javascript html canvas


【解决方案1】:

您可以在 JavaScript 中控制loading images。但是,您似乎无法强制浏览器卸载图像。 browser will decide for itself when to unload it from memory,只要您的代码中不再有对该图像的任何引用。

【讨论】:

  • 感谢您的回答,但对我来说,这似乎仍然会在当前未使用的精灵上浪费内存。
【解决方案2】:

1) 加载图像 - 使用 js 函数,在页面加载时触发并确保您在图像上设置足够的缓存,以便它们只从网络请求一次,并在再次请求时从浏览器的缓存中提供。有多种方法可以做到这一点,但最好使用 js,因为您需要为步骤 2 保留这些图像的引用变量。

2) 卸载图像 - 浏览器中还没有从内存中卸载图像。但是,您可以在不使用image to a smaller image 的源时切换它。

3) 渲染函数 - 您需要编写一个开关函数来在需要时切换图像并在不需要时切换图像。

【讨论】:

  • 你的回答给了我一个想法。更改图像的 SRC 是否可行,然后在去其他地方时使用它?例如,在房间 A 中,来源为 blackBlock 且 id 为 'basicBlock' 的图像,以及房间 B 中的来源为 whiteBlock 且 id 为 'basicBlock' 的图像。
  • 更改 src 是一个非常糟糕的主意。就像第 2 点所说的那样,它甚至不会释放内存,您只会加载 2 张图像而不是 1 张... + 下次您需要使用它时,您将不得不等待图像再次被解析,而不是能够直接使用它。
  • 是的,这就是我的观点。第 2 点没有意义,就像这个答案一样。
  • @Vakore:1) 是的,保持地图和命名约定可以帮助您编写最佳算法。 2) 浏览器需要时,GC 会进行内存清理。查看这个答案以了解此循环:stackoverflow.com/questions/18800440/… 2) 的目的是删除对图像的引用,因此它在运行时由 GC 收集。
  • 您可以在节点中触发 GC:stackoverflow.com/questions/27321997/… 但是我没有使用电子的经验。这个链接说它应该表现得像浏览器:electronjs.org/blog/electron-internals-weak-references 你需要运行一些测试/创建一个 POC 来检查它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-01
  • 2012-02-24
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
相关资源
最近更新 更多