Fase 4: gestiamo i proiettili nemici | Aulab
TECH SUMMER LAB 🚀 Open Month
| 6 lezioni gratuite per orientarti al meglio e iniziare a costruire il tuo futuro digitale! Iscriviti gratis

GUIDE PER ASPIRANTI PROGRAMMATORI

Fase 4: gestiamo i proiettili nemici

Creazione della Classe InvaderProjectile Per far sì che gli invaders possano davvero attaccare la tua navicella, dobbiamo creare dei proiettili che gli invaders possano sparare verso il basso. Questa volta useremo una classe simile a quella dei proiettili del giocatore, ma con alcune differenze. Aggiungi questo codice al tuo file index.js:   class InvaderProjectile {…

Lezione 15 / 17
Enza Neri
Immagine di copertina

Vuoi avviare una nuova carriera o fare un upgrade?

Trova il corso Digital & Tech più adatto a te nel nostro catalogo!

Creazione della Classe InvaderProjectile

Per far sì che gli invaders possano davvero attaccare la tua navicella, dobbiamo creare dei proiettili che gli invaders possano sparare verso il basso. Questa volta useremo una classe simile a quella dei proiettili del giocatore, ma con alcune differenze.

Aggiungi questo codice al tuo file index.js:

class InvaderProjectile {
    constructor({ position, velocity }) {
        this.position = position;
        this.velocity = velocity;
        this.width = 3; // Larghezza del proiettile
        this.height = 10; // Altezza del proiettile
    }

    draw() {
        c.fillStyle = 'white'; // Colore del proiettile nemico
        c.fillRect(this.position.x, this.position.y, this.width, this.height); // Disegna il proiettile come un rettangolo
    }

    update() {
        this.draw(); // Disegna il proiettile
        this.position.x += this.velocity.x; // Sposta il proiettile in orizzontale (anche se non lo facciamo per ora)
        this.position.y += this.velocity.y; // Sposta il proiettile verso il basso
    }
}

Cosa fa questo codice?

  1. Creare un proiettile nemico (InvaderProjectile): questa classe rappresenta i proiettili sparati dagli invaders. Ogni proiettile ha una posizione iniziale e una velocità.
  2. Disegnare il oroiettile (draw): il proiettile viene disegnato come un piccolo rettangolo bianco sul canvas.
  3. Aggiornare la posizione (update): la funzione update sposta il proiettile verso il basso, simulando il tiro degli invaders.

Permettere ai nemici di sparare

Ora che abbiamo una classe per i proiettili nemici, dobbiamo collegarla alla nostra griglia di invaders in modo che possano sparare. Questo è stato in parte fatto nella sezione precedente, ma ora andremo a completare il tutto.

Aggiornamento della Funzione animate

Assicuriamoci che i proiettili nemici siano generati e gestiti correttamente durante il gioco. Modifichiamo la funzione animate per gestire questo aspetto:

function animate() {
    requestAnimationFrame(animate);
    c.fillStyle = 'black';
    c.fillRect(0, 0, canvas.width, canvas.height);

    player.update();

    projectiles.forEach((projectile, index) => {
        if (projectile.position.y + projectile.radius <= 0) {
            setTimeout(() => {
                projectiles.splice(index, 1);
            }, 0);
        } else {
            projectile.update();
        }
    });

    invaderProjectiles.forEach((invaderProjectile, idx) => {
        if (invaderProjectile.position.y + invaderProjectile.height >= canvas.height) {
            setTimeout(() => {
                invaderProjectiles.splice(idx, 1);
            }, 0);
        } else {
            invaderProjectile.update();
        }

        // Verifica se il proiettile colpisce il giocatore
        if (
            invaderProjectile.position.y + invaderProjectile.height >= player.position.y &&
            invaderProjectile.position.x + invaderProjectile.width >= player.position.x &&
            invaderProjectile.position.x <= player.position.x + player.width
        ) {
            setTimeout(() => {
                invaderProjectiles.splice(idx, 1);
                player.opacity = 0;
                game.over = true;
            }, 0);

            setTimeout(() => {
                game.active = false;
                ending.style.display = 'block'; // Mostra il messaggio di Game Over
            }, 2000);

            createParticles({
                object: player,
                color: 'white',
                fades: true
            });
        }
    });

    grids.forEach((grid, gridIndex) => {
        grid.update();

        if (frames % 100 === 0 && grid.invaders.length > 0) {
            grid.invaders[Math.floor(Math.random() * grid.invaders.length)].shoot(invaderProjectiles);
        }

        grid.invaders.forEach((invader, i) => {
            invader.update({ velocity: grid.velocity });

            projectiles.forEach((projectile, j) => {
                if (
                    projectile.position.y - projectile.radius <= invader.position.y + invader.height &&
                    projectile.position.x + projectile.radius >= invader.position.x &&
                    projectile.position.x - projectile.radius <= invader.position.x + invader.width &&
                    projectile.position.y + projectile.radius >= invader.position.y
                ) {
                    setTimeout(() => {
                        const invaderFound = grid.invaders.find(invader2 => invader2 === invader);
                        const projectileFound = projectiles.find(projectile2 => projectile2 === projectile);

                        if (invaderFound && projectileFound) {
                            score += 100;
                            scoreElement.innerHTML = score;

                            createParticles({
                                object: invader,
                                fades: true
                            });

                            grid.invaders.splice(i, 1);
                            projectiles.splice(j, 1);

                            if (grid.invaders.length > 0) {
                                const firstInvader = grid.invaders[0];
                                const lastInvader = grid.invaders[grid.invaders.length - 1];

                                grid.width = lastInvader.position.x - firstInvader.position.x + lastInvader.width;
                                grid.position.x = firstInvader.position.x;
                            } else {
                                grids.splice(gridIndex, 1);
                            }
                        }
                    }, 0);
                }
            });
        });
    });

    if (keys.arrowLeft.pressed && player.position.x >= 0) {
        player.velocity.x = -10;
        player.rotation = -0.15;
    } else if (keys.arrowRight.pressed && player.position.x + player.width <= canvas.width) {
        player.velocity.x = 10;
        player.rotation = 0.15;
    } else {
        player.velocity.x = 0;
        player.rotation = 0;
    }

    if (frames % randomInterval === 0) {
        grids.push(new Grid());
        randomInterval = Math.floor(Math.random() * 500 + 500);
        frames = 0;
    }

    frames++;
}

animate();

Cosa fa questo codice?

  1. Gestione dei proiettili nemici (invaderProjectiles.forEach): ogni proiettile sparato dagli invaders viene controllato e aggiornato. Se un proiettile raggiunge il bordo inferiore dello schermo, viene rimosso dall’array.
  2. Collisione con il giocatore: se un proiettile nemico colpisce la navicella del giocatore, l’opacità della navicella viene impostata a 0 (la navicella scompare), e il gioco finisce. Dopo un breve ritardo, viene visualizzato il messaggio “GAME OVER”.
  3. Sparare proiettili dagli invaders: ogni tanto, un invader casuale tra quelli presenti nella griglia spara un proiettile verso il giocatore.

Hai bisogno di informazioni? 🙋🏻‍♂️

Parliamone! Scrivici su Whatsapp e risponderemo a tutte le tue domande per capire quale dei nostri corsi è il più adatto alle tue esigenze.

Oppure chiamaci al 800 128 626