如何复制一个p5.js的已加载图片数组?

前端开发 2026-07-12

我在用p5.js库开发一个基于JavaScript的电子游戏。

我想通过复制已加载的图片来加速游戏加载,而不是重复加载同一张图片。

有没有办法复制一组通过loadImage API调用加载的图片?

复制后,我想重新给它们着色。我这样做,原始图片和拷贝都被着色。

这是我在复制时遇到困难的p5.js API调用,不论是使用浅拷贝还是深拷贝方案: loadImage(URL). 我甚至尝试过JavaScript的 structuredClone,但我得到的错误是数组不能被克隆。是真的吗?

下面给出一个我想避免的情况的例子:

computer_greenCar_images[13] = loadImage('carImages P5 Origin/Car292.png');
  computer_greenCar_images[14] = loadImage('carImages P5 Origin/Car315.png');
  computer_greenCar_images[15] = loadImage('carImages P5 Origin/Car337.png');
computer_orangeCar_images[13] = loadImage('carImages P5 Origin/Car292.png');
  computer_orangeCar_images[14] = loadImage('carImages P5 Origin/Car315.png');
  computer_orangeCar_images[15] = loadImage('carImages P5 Origin/Car337.png');
computer_purpleCar_images[13] = loadImage('carImages P5 Origin/Car292.png');
  computer_purpleCar_images[14] = loadImage('carImages P5 Origin/Car315.png');
  computer_purpleCar_images[15] = loadImage('carImages P5 Origin/Car337.png');

我尝试了这个,在去绘制图像时,什么也没有显示。

for (let i = 0; i < computer_greenCar_images.length; i++) {
// Use the .get() method (which returns a new p5.Image object) to create a copy
let imgCopy = computer_greenCar_images[i].get();
computer_orangeCar_images[i] = imgCopy;

我也尝试过使用这种技术进行拷贝,但仍然无法得到唯一的拷贝。当我给绿色的汽车着色时,橙色的汽车也会跟着着色。

    function UTL_copy_green_to_orange() {
  for (let i = 0; i < computer_greenCar_images.length; i++) {
    computer_orangeCar_images[i] = createImage(
      computer_greenCar_images[i].width,
      computer_greenCar_images[i].height,
    );

    computer_orangeCar_images[i].copy(
      computer_greenCar_images[i],
      0,
      0,
      computer_greenCar_images[i].width,
      computer_greenCar_images[i].height,
      0,
      0,
      computer_orangeCar_images[i].width,
      computer_orangeCar_images[i].height,
    );
  }
}

有什么想法吗?还是这在p5.js中做不到?

谢谢!!

解决方案

你可以使用 get()loadPixels() 来复制图像,如果你需要对不同的图像进行不同的着色,这点是必要的:

const originals = [];
const copies = [];
const urls = [
  // if these links go down in the future, drop in any CORS-friendly image links
  "https://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg",
  "https://upload.wikimedia.org/wikipedia/commons/e/e1/Cattle_tyrant_%28Machetornis_rixosa%29_on_Capybara.jpg",
  "https://upload.wikimedia.org/wikipedia/commons/0/02/Capybara.jpg",
];

function preload() {
  for (const url of urls) {
    originals.push(loadImage(url));
  }
}

function setup() {
  createCanvas(900, 400);

  for (const [i, original] of originals.entries()) {
    const img = original.get();
    copies.push(img);
    img.loadPixels();

    // prove that they're actually copies by modifying pixels
    for (let p = 0; p < img.pixels.length; p += 4) {
      img.pixels[p] = i * 120;
    }

    img.updatePixels();
  }

  noLoop();
  const w = width / originals.length;

  for (const [i, original] of originals.entries()) {
    image(original, i * w, 0, w, height / 2);
    image(copies[i], i * w, height / 2, w, height / 2);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>

也就是说,浏览器缓存应该能让重复请求不再成为问题,前提是它能够检测到p5发送的重复请求 fetch 请求

如果浏览器缓存没有在网络选项卡中按你预期处理这些请求,p5play,一个基于p5.js的包装器,显式缓存图像

由于你的实际目标是优化一个加载缓慢的脚本,我建议提供完整的问题上下文(完整且可运行的代码)。也有可能图片本身没有被优化,或者除了图像加载之外还有其他瓶颈。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章