问题描述
基本问题在标题中。我使用一个函数来定义一个带有一组特定参数的 p5.js 实例。草图本身运行一个浏览器内的视频游戏。当游戏中发生一组事件中的任何一个时,草图被移除,游戏结束。给定草图的参数值数组,我使用 for 循环来构造使用数组的每个元素定义的草图。我预计在 for 循环的单次迭代中,定义的草图将在 for 循环进行和下一个草图被定义和运行之前完成(即运行直到删除)。然而,实际发生的是,一旦定义了草图,循环就会进行并定义下一个草图。这会导致所有草图同时在浏览器中运行。
如何确保每个草图在下一个运行之前完成?我的猜测是我可能需要将一些变量传递给每个调用 noLoop() 和 Loop() 的草图,但我不确定。下面是一个 HTML 文件形式的最小工作示例:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/p5@1.2.0/lib/p5.js"></script>
</head>
<body></body>
<script>
/* Function to define sketch with parameter 'a' */
function definesketch(a) {
let sketch = function(p) {
let x = 100;
let y = 100;
p.setup = function() {
p.createCanvas(700,410);
};
p.draw = function() {
p.background(0);
p.fill(255);
p.rect(x,y,a*50,a*50);
};
/* Remove sketch on mouse press */
p.mousepressed = function() {
p.remove();
};
};
}
/* Initialize sketch variable */
let trialSketch;
/* Array of parameters */
let param_seq = [0,1,2];
/* For loop to sequentially run sketches with different parameters */
for(let i = 0; i < param_seq.length; i++ ) {
trialSketch = definesketch(param_seq[i]);
new p5(trialSketch);
}
</script>
</html>
解决方法
正如用户 Pr0tonX 在 Processing forum 处所指出的,解决方案是设置一个布尔值来检查草图是否正在运行,并在其上设置一个侦听器,如下所示:
<!DOCTYPE html>
<html>
<head>
<script src="p5.min.js"></script>
</head>
<body></body>
<script>
// listened variable
// we set a listner which wiil be fired each time the value of bool is changed.
let sketchIsRunning = {
$: false,listener: function(val) {},set bool(val) {
this.$ = val;
this.listener(val);
},get bool() {
return this.value;
},registerListener: function(listener) {
this.listener = listener;
}
};
/* Function to define sketch with parameter 'a' */
function defineSketch(a) {
return function(p) {
let x = 100;
let y = 100;
p.setup = function() {
p.createCanvas(700,410);
console.log('cool')
};
p.draw = function() {
p.background(0);
p.fill(255);
p.rect(x,y,a*50,a*50);
};
/* Remove sketch on mouse press */
p.mousePressed = function() {
p.remove();
sketchIsRunning.bool = !sketchIsRunning.bool
console.log('sketch is running ?',sketchIsRunning.bool)
};
};
}
/* Initialize sketch variable */
let trialSketch;
/* Array of parameters */
let param_seq = [0,1,2];
// we nest a call to the function itself to loop through the param.seq array
const instanceP5sketches = (i = 0) => {
sketchIsRunning.$ = !sketchIsRunning.$;
trialSketch = defineSketch(param_seq[i]);
new p5(trialSketch);
sketchIsRunning.registerListener(function(val) {
if (param_seq.length - 1 >= i){
instanceP5sketches(i+1);
} else {
console.log('No more sketches.')
}
});
}
instanceP5sketches();
</script>
</html>