Estoy buscando una función que se llame una vez y luego se rearme de acuerdo con un estado booleano.
Después de un poco de piratería, encontré que la respuesta de Paul a continuación era una forma efectiva de ejecutar / rearmar una función dentro del ciclo de dibujo.
Sin embargo, descubrí que al incorporar este código con una clase con más de una instancia dentro de un bucle for, la función se activa y se restablece varias veces por instancia. según mi código de ejemplo a continuación.
let instances = []; function setup() { createCanvas(400, 400); for (let i = 0; i < 4; i++) { instances.push(new Ball(50, random(30,370))); } } const [happenOnce, reset] = makeRunOnce(() => { console.log("ball has crossed the line!"); }); function makeRunOnce(fn) { let hasRun = false; return [ // run () => { if (!hasRun) { fn(); hasRun = true; } }, // reset () => { hasRun = false; } ] } function draw() { background(220); line(200, 0, 200, height); for (let i = 0; i < instances.length; i++) { instances[i].showBall(); instances[i].moveBall(); if(instances[i].returnTrue()) { happenOnce(); } else { reset(); } } } class Ball{ constructor(x, y) { this.x = x; this.y = y this.r = 10; this.t = random(); } showBall() { ellipse(this.x, this.y, this.r * 2); } moveBall() { this.x += this.t; } returnTrue() { return this.x + this.r > 200; } }¿Alguien tiene alguna sugerencia sobre cómo puedo hacer que la función se ejecute una vez cuando el método de clase devuelve verdadero y se restablece cuando es falso para cada instancia?
Parece que podría estar complicando un poco las cosas, pero todo lo que necesita aquí es la capacidad de restablecer ese indicador executed a falso. Aquí hay un ejemplo con una función auxiliar makeRunOnce que toma una función y devuelve dos funciones en una matriz. La primera función ejecuta la función original solo la primera vez que se llama (ya sea inicialmente o después de un restablecimiento), y la segunda función restablece el estado a no llamado. Para probar este ejemplo, hacer clic dibuja un círculo la primera vez que hace clic, los clics adicionales se ignorarán hasta que haga doble clic, lo que restablece el estado de modo que el siguiente clic dibujará otro círculo.
function setup() { createCanvas(windowWidth, windowHeight); } const [drawCircleOnce, resetDrawCircle] = makeRunOnce(() => { ellipse(mouseX, mouseY, 20, 20); }); let mouseHasBeenClicked = false; function draw() { if (mouseHasBeenClicked) { drawCircleOnce(); } else { resetDrawCircle(); } } // Note: instead of setting the mouseHasBeenClicked flag here // we could just call drawCircleOnce() directly, and then // resetDrawCircle() in doubleClicked. The draw() function would // then be a no-op. I've use this flag to more closely // approximate the apparent structure of your code. function mouseClicked() { mouseHasBeenClicked = true; } function doubleClicked() { // reset mouseHasBeenClicked = false; } function makeRunOnce(fn) { let hasRun = false; return [ // run () => { if (!hasRun) { fn(); hasRun = true; } }, // reset () => { hasRun = false; } ] } <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>