我目前正在使用实例模式构建一个网站,该网站有多个 p5.js 画布和我自己的图像,因此我可以在 html 页面上获得多个画布。但是,我认为我的语法不正确。
// first sketch
var sketch1 = function (p) {
const NUM_IMGS = 4;
imgs = [];
let currentImg = 0;
p.preload = function () {
for (let i = 0; i < NUM_IMGS; i++) {
imgs[1] = p.loadImage("images/mag.png");
imgs[2] = p.loadImage("images/outfits.png");
imgs[3] = p.loadImage("images/photographer1.png");
imgs[4] = p.loadImage("images/photographer2.png");
}
};
p.setup = function () {
const sketch1 = p.createCanvas(450, 300);
};
setupButtons();
};
p.draw = function () {
p.image(imgs[currentImg], 0, 0);
};
const setupButtons = (_) => {
previous = p.createButton("⏪");
previous.position(p.width * 0.6 - 100, p.height);
previous.mouseClicked((_) => {
if (p.currentImg > 0) p.currentImg--;
});
next = p.createButton("⏩");
next.position(p.width * 0.3 + 100, p.height);
next.mouseClicked((_) => {
if (p.currentImg < p.imgs.length - 1) p.currentImg++;
});
};
// second sketch
var sketch2 = function (p) {
let y;
let z;
let a;
let switcher;
let currentImage;
p.preload = function () {
y = p.loadImage("girls.png");
z = p.loadImage("bow.png");
a = p.loadImage("rose.png");
b = p.loadImage("reds.png");
};
p.setup = function () {
p.createCanvas(250, 300);
switcher = createButton("see my pics");
switcher.position(900, 1200);
switcher.mousePressed(changeImg);
};
p.draw = function () {};
p.changeImg = function () {
if (currentImage == y) currentImage = z;
else if (currentImage == z) currentImage = a;
else if (currentImage == a) currentImage = b;
else {
currentImage = y;
}
image(currentImage, 0, 0, 250, 300);
};
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js"></script>
我收到错误消息“p is not defined”。我似乎无法让 p5 激活“实例模式”使用此代码作为参考,并使用此代码作为参考
忠告:慢点!这段代码看起来像是一口气写出来的,盲目地希望/假设它会起作用。如果没有,就没有明显的调试入口点,因为复杂性已经远远超出了您的理解范围。
更好的策略是慢慢编码,一旦做出任何更改就运行代码以验证它是否仍然有效。如果它不起作用,您将确切地知道如何修复它,因为您只做了一个小改动。
从简单、最小的示例开始,例如文档中的 p5 实例模式示例,然后只有在您彻底测试代码以说服自己它有效后才构建。两个链接的草图都是非实例模式幻灯片。与其尝试让实例模式、2 个草图和幻灯片逻辑同时运行,不如一次专注于一个目标。从让显示单个图像的单个实例开始工作。然后把它做成幻灯片。然后添加第二个草图。如果这些步骤太大,请将问题离散化为更小的步骤,这些步骤是可实现和可验证的。
你可以把编程想象成探索一个满是坑的黑屋子。如果你不情愿地冲进去,你就会掉进坑里。如果你走得慢,测试你前面的下一步,你就会安全地到达目标。
这是我注意到的一些错误的列表:
p.draw
和 setupButtons
在全球范围内,导致您的主要错误。这些需要在 p5 实例闭包内,在那里它们可以访问 p
参数。如果您使用 autoformatter(我已经为您在问题代码上运行了一个),您可能已经看到了这一点。new p5(sketch1)
的调用以初始化实例。p.
的困惑。如果您拥有该变量,并且它是在您的草图闭包中使用 let
声明的,请不要在前面添加 p.
。 p.
只是用来指代p5库中的一段数据。例子:
p.changeImg
应该是const changeImg
p.imgs
应该是imgs
p.currentImg
应该是currentImg
createButton("see my pics");
应该是p.createButton("see my pics");
for (let i = 0; i < NUM_IMGS; i++) {
除了将相同的图像一遍又一遍地加载到索引 1、2、3、4 之外什么都不做。imgs[0]
从未设置过。setupButtons();
应从 p5 的 setup
函数中调用,以便正确初始化实例。let
和 const
严格限定变量范围。示例包括 next
、previous
和 imgs
。 linter 会告诉你这些错误。在脚本顶部添加 "use strict";
也很有帮助。changeImg
在数组更易于管理时使用单独的变量。currentImage
从未在草图 2 中初始化。这里的代码远非完美,但解决了上述大部分问题。我已经移动了几个位置并添加了虚拟图像以使示例可以运行。我希望你能从这里调整到你想要的。
// first sketch
var sketch1 = function (p) {
const imgs = [];
let currentImg = 0;
p.preload = function () {
imgs[0] = p.loadImage("http://placekitten.com/450/300");
imgs[1] = p.loadImage("http://placekitten.com/450/301");
imgs[2] = p.loadImage("http://placekitten.com/450/302");
imgs[3] = p.loadImage("http://placekitten.com/450/303");
};
p.setup = function () {
const sketch1 = p.createCanvas(450, 300);
setupButtons();
};
const setupButtons = () => {
const previous = p.createButton("⏪");
previous.position(10, 10);
previous.mouseClicked(() => {
if (currentImg > 0) currentImg--;
});
const next = p.createButton("⏩");
next.position(40, 10);
next.mouseClicked(() => {
if (currentImg < imgs.length - 1) currentImg++;
});
};
p.draw = function () {
p.image(imgs[currentImg], 0, 0);
};
};
// second sketch
var sketch2 = function (p) {
let images;
let switcher;
let currentImage = 0;
p.preload = function () {
images = [
p.loadImage("http://placekitten.com/250/300"),
p.loadImage("http://placekitten.com/250/301"),
p.loadImage("http://placekitten.com/250/302"),
p.loadImage("http://placekitten.com/250/303"),
]
};
p.setup = function () {
p.createCanvas(250, 300);
switcher = p.createButton("see my pics");
switcher.position(90, 120);
switcher.mousePressed(changeImg);
p.noLoop();
};
const changeImg = function () {
p.image(images[currentImage], 0, 0, 250, 300);
currentImage = (currentImage + 1) % images.length;
};
};
new p5(sketch1);
new p5(sketch2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js"></script>