在 For 循环中按顺序创建 p5.js 个实例,但仅在前一个完成之后
Create p5.js Instances Sequentially in For Loop But Only After the Previous One Finishes
基本问题在标题里。我使用一个函数来定义具有一组特定参数的 p5.js 实例。草图本身 运行 是一个 in-browser 电子游戏。当游戏中发生一组事件中的任何一个时,草图将被移除,游戏结束。给定草图的参数值数组,我使用 for-loop 来构建使用数组的每个元素定义的草图。我预计在 for-loop 的单次迭代中,定义的草图将在 for-loop 进行之前完成(即 运行 直到删除)并且下一个草图被定义并且 运行 .然而,实际发生的是,一旦定义了草图,循环就会继续并定义下一个草图。这会导致所有草图 运行 同时出现在浏览器中。
如何确保每个草图在下一个 运行 之前完成?我的猜测是我可能需要将一些变量传递给每个调用 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>
正如 Processing forum 上的用户 Pr0tonX 所指出的,解决方案是设置一个布尔值来检查草图是否为 运行,并在其上设置一个侦听器,如下所示:
<!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>
基本问题在标题里。我使用一个函数来定义具有一组特定参数的 p5.js 实例。草图本身 运行 是一个 in-browser 电子游戏。当游戏中发生一组事件中的任何一个时,草图将被移除,游戏结束。给定草图的参数值数组,我使用 for-loop 来构建使用数组的每个元素定义的草图。我预计在 for-loop 的单次迭代中,定义的草图将在 for-loop 进行之前完成(即 运行 直到删除)并且下一个草图被定义并且 运行 .然而,实际发生的是,一旦定义了草图,循环就会继续并定义下一个草图。这会导致所有草图 运行 同时出现在浏览器中。
如何确保每个草图在下一个 运行 之前完成?我的猜测是我可能需要将一些变量传递给每个调用 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>
正如 Processing forum 上的用户 Pr0tonX 所指出的,解决方案是设置一个布尔值来检查草图是否为 运行,并在其上设置一个侦听器,如下所示:
<!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>