TL; DR ¿Por qué la pelota no rebota en el borde en el siguiente enlace?
Actualmente estoy revisando los videos de CodingTrain P5JS. Lo que estoy tratando de lograr es un simple botón de alternar:
https://editor.p5js.org/S_Oda/sketches/uF_dgcQP-
Cuando el botón está 'encendido', cambia a rojo y la pelota se mueve hasta que toca el borde izquierdo o derecho, donde rebota y cambia en la dirección opuesta. Cuando el botón se desactiva, la pelota se congelará en su lugar y reanudará el movimiento cuando se vuelva a presionar el botón.
Mi problema es que cuando la pelota golpea el borde, parece fallar en su lugar. El rebote estaba funcionando antes de que introdujera el botón de alternancia. El resonar de mi código es que si vinculo la variable 'velocidad' de la pelota para que dependa de un booleano ("ballState"), entonces el botón puede cambiar si 'ballState' es verdadero o falso, es decir, moverse o no moverse . Entonces me pregunto si el problema está aquí en alguna parte:
//Tying speed to ballState so that I can toggle the ball movement with the button if (!ballState) { speed = 0; } else if (ballState) { speed = 8; } //Why does this not result in the ball bouncing off of the edge of the canvas? if (x >= width || (x <= -1 && ballState)) { speed = speed * -1; }Agradecería si alguien pudiera decirme qué estoy haciendo mal, sin introducir nuevos conceptos/soluciones alternativas, ya que estoy tratando de aprender las cosas paso a paso. ¡Muchas gracias de antemano!
Código completo:
var btn = false; var ballState = false; var x = 0; var speed = 0; function setup() { createCanvas(600, 400); background(0); rectMode(CENTER); } function draw() { background(0); stroke(255); //Button if (btn) { stroke(255, 0, 0); fill(255, 0, 0); push(); translate(0, 180); text("ON", width / 2, height / 2, 20, 20); pop(); } else { noFill(0); push(); translate(0, 180); text("OFF", width / 2, height / 2, 20, 20); pop(); } rect(width / 2, 330, 120, 60); //Ball x = x + speed; push(); noStroke(); fill(0, 0, 255); ellipse(x, height / 2, 100, 100); pop(); //Tying speed to ballState so that I can toggle the ball movement with the button if (!ballState) { speed = 0; } else if (ballState) { speed = 8; } //Why does this not result in the ball bouncing off of the edge of the canvas? if (x >= width || (x <= -1 && ballState)) { speed = speed * -1; } } //Button toggle function mousePressed() { if (mouseX >= 239 && mouseX <= 360 && mouseY >= 300 && mouseY <= 360) { btn = !btn; ballState = !ballState; } }El problema es principalmente este, que ejecuta cada cuadro en la función de draw :
// ... else if (ballState) { speed = 8; } ... donde ballState se llama más acertadamente isBallMoving .
Puedes pensar speed = speed * -1; invierte la pelota, pero en el siguiente marco de renderizado, ballState siendo verdadero significa que la speed = 8; en el bloque de código anterior lo vuelve a colocar en la dirección de avance, anulando su intención.
Otro tema a considerar es este: si x >= width y speed *= -1 para invertir la dirección, ¿la x de la bola seguirá siendo >= width en el siguiente cuadro? Si es así, en igualdad de condiciones, la speed *= -1 ocurrirá nuevamente y la pelota simplemente vibrará en su lugar, invirtiendo la dirección infinitamente.
Dejaré que usted determine la mejor manera de resolver estos problemas, pero en un nivel alto, querrá capturar y verificar algo más que ballState para su lógica de configuración de velocidad. También es posible que necesite una forma de que los objetos que han chocado con una pared se "empujen" hacia afuera de la pared hasta que se resuelva la colisión.