在 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>