Pelota, rebotes y colisiones
Objetivo: mover la pelota, resolver rebotes contra paredes y detectar contacto con las paletas.
1. Movimiento de la pelota
La pelota usa velocidad independiente en X e Y. En cada frame, la posición se incrementa con esa velocidad.
ball.x += ball.vx;
ball.y += ball.vy;ball.vx desplaza horizontalmente. ball.vy desplaza verticalmente. Si vx es positivo, la pelota avanza a la derecha; si es negativo, avanza a la izquierda. Si vy es positivo, baja; si es negativo, sube.
2. Rebote contra techo y piso
La pelota debe invertir su dirección vertical al tocar el borde superior o inferior.
if (ball.y - ballR < 0 || ball.y + ballR > H) {
ball.vy *= -1;
}ball.y - ballR representa el borde superior de la pelota. ball.y + ballR representa el borde inferior. Luego de detectar el contacto, se resuelve la consecuencia invirtiendo vy.
3. Colisión con la paleta del jugador
La pelota colisiona con la paleta izquierda cuando su borde izquierdo alcanza el borde derecho de la paleta, su centro vertical está dentro del rango de la paleta y la pelota se mueve hacia la izquierda.
if (ball.x - ballR < player.x + paddleW &&
ball.y > player.y &&
ball.y < player.y + paddleH &&
ball.vx < 0) {
ball.vx *= -1.08;
let offset = (ball.y - (player.y + paddleH / 2)) / (paddleH / 2);
ball.vy = offset * 5;
score += 10;
ctx.onScore(score);
}La condición ball.vx < 0 confirma que la pelota se mueve hacia la paleta izquierda. Luego de detectar la colisión, ball.vx *= -1.08 invierte la dirección horizontal y aumenta la velocidad. offset calcula el punto de contacto dentro de la paleta.
4. Cálculo del ángulo de salida
offset produce un valor aproximado entre -1 y 1. Cerca del centro vale 0. Cerca del borde superior es negativo. Cerca del borde inferior es positivo.
let offset = (ball.y - (player.y + paddleH / 2)) / (paddleH / 2);
ball.vy = offset * 5;ball.y es el centro vertical de la pelota. player.y + paddleH / 2 es el centro vertical de la paleta. La resta mide si el golpe ocurrió arriba o abajo del centro. Dividir por paddleH / 2 normaliza ese valor.
5. Colisión con la CPU
La paleta derecha usa la misma regla, pero se revisa el borde derecho de la pelota y se exige que la pelota avance hacia la derecha.
if (ball.x + ballR > computer.x &&
ball.y > computer.y &&
ball.y < computer.y + paddleH &&
ball.vx > 0) {
ball.vx *= -1.05;
let offset = (ball.y - (computer.y + paddleH / 2)) / (paddleH / 2);
ball.vy = offset * 5;
}ball.x + ballR representa el borde derecho de la pelota. computer.x representa el borde izquierdo de la paleta derecha. ball.vx > 0 evita procesar una colisión cuando la pelota ya se aleja.