Capítulo 05

Score, saque y dificultad

Objetivo: detectar puntos, reiniciar la pelota después de cada punto y controlar la dirección del siguiente saque.

1. Detectar punto

Un punto ocurre cuando la pelota sale completamente por la izquierda o por la derecha. Se usa un margen de 20px para evitar reinicios justo en el borde visible.

Punto jugador / CPU
if (ball.x < -20) {
    computer.score++;
    serveDir = 1;
    resetBall();
}

if (ball.x > W + 20) {
    player.score++;
    serveDir = -1;
    resetBall();
}

Si la pelota sale por la izquierda, anota la CPU y el siguiente saque va hacia la derecha (serveDir = 1). Si sale por la derecha, anota el jugador y el siguiente saque va hacia la izquierda (serveDir = -1).

2. Reiniciar solo la pelota

Después de un punto se conserva el marcador de ambos lados. Por eso se usa resetBall() y no reset().

resetBall
function resetBall() {
    ball = {
        x: W / 2,
        y: H / 2,
        vx: 4 * serveDir,
        vy: p.random(-2, 2)
    };
    trail = [];
}

x e y centran la pelota. vx usa serveDir para definir el lado inicial. vy usa un valor aleatorio pequeño para variar el saque. trail se limpia para que la estela anterior no aparezca después del punto.

3. Score externo e interno

El juego puede manejar dos tipos de puntaje: marcador de partida y score del HUD externo. En este Pong, player.score y computer.score son el marcador visual. score se usa para informar progreso al HUD externo.

Score por golpe
score += 10;
ctx.onScore(score);

El score externo aumenta cuando el jugador golpea la pelota. ctx.onScore(score) sincroniza ese valor con la interfaz HTML.

4. Aumento de velocidad por impacto

La pelota acelera al rebotar contra las paletas. Esto se hace multiplicando vx por un factor mayor que 1 al invertir dirección.

Aceleración de pelota
ball.vx *= -1.08; // jugador
ball.vx *= -1.05; // CPU

El signo negativo cambia la dirección horizontal. El valor absoluto aumenta porque el factor es mayor que 1. Usar factores diferentes permite que los golpes del jugador aceleren un poco más que los de la CPU.

5. Bloque update con scoring

Al final de update() se revisa si la pelota salió del campo. Esta revisión debe ocurrir después de mover la pelota y resolver rebotes o paletas.

Scoring dentro de update
function update() {
    // movimiento de paletas
    // movimiento de pelota
    // rebotes y colisiones

    if (ball.x < -20) {
        computer.score++;
        serveDir = 1;
        resetBall();
    }

    if (ball.x > W + 20) {
        player.score++;
        serveDir = -1;
        resetBall();
    }
}

Esta ubicación evita que se reinicie la pelota antes de evaluar una posible colisión válida del frame actual.