Capítulo 07

Colisiones, score, partículas y shake

Objetivo: entender qué cambia cuando una bala impacta contra un enemigo o contra la nave.

1. Bala del jugador contra enemigo

Impacto: enemigo muere, score sube y aparecen partículas
Impacto contra enemigo
if (p.abs(bullets[i].x - e.x) < e.w / 2 + 3 && p.abs(bullets[i].y - e.y) < e.h / 2 + 4) {
    e.alive = false;
    bullets.splice(i, 1);
    score += (e.type + 1) * 10;
    for (let j = 0; j < 8; j++) {
        particles.push({ x: e.x, y: e.y, vx: p.random(-3, 3), vy: p.random(-3, 3), life: p.random(12, 25),
            col: e.type === 2 ? [255, 80, 80] : e.type === 1 ? [255, 180, 40] : [80, 255, 120] });
    }
    shake = 4;
    ctx.onScore(score);
    break;
}

La colisión compara distancia horizontal y vertical entre el centro de la bala y el centro del enemigo. El color de las partículas depende de e.type, la misma categoría que se usa para dibujar enemigos y calcular score.

2. Bala enemiga contra jugador

Daño al jugador
if (p.abs(enemyBullets[i].x - player.x) < shipW / 2 && p.abs(enemyBullets[i].y - player.y) < shipH / 2) {
    enemyBullets.splice(i, 1);
    lives--;
    shake = 8;
    for (let j = 0; j < 15; j++) {
        particles.push({ x: player.x, y: player.y, vx: p.random(-4, 4), vy: p.random(-4, 4), life: p.random(15, 35),
            col: [100, 180, 255] });
    }
    ctx.onScore(score);
    if (lives <= 0) gameOver = true;
}

El impacto contra jugador es más fuerte visualmente: usa más partículas y shake = 8. Si las vidas llegan a cero, la partida entra en gameOver.

3. Derrota por invasión

Enemigo demasiado bajo
for (let e of enemies) {
    if (e.alive && e.y + e.h / 2 > player.y - 8) { gameOver = true; }
}

El jugador también pierde si un enemigo vivo baja hasta la zona de la nave, aunque todavía queden vidas.