Fase 5: implementiamo il sistema di punteggio e gli effetti grafici | 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 5: implementiamo il sistema di punteggio e gli effetti grafici

Creazione del sistema di punteggio Per rendere il gioco più coinvolgente, aggiungiamo un sistema di punteggio che aumenta ogni volta che un invader viene abbattuto. Il punteggio è già collegato nel codice che abbiamo scritto in precedenza, ma vediamo esattamente come funziona. Il punteggio viene aggiornato ogni volta che un proiettile del giocatore colpisce un…

Lezione 16 / 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 del sistema di punteggio

Per rendere il gioco più coinvolgente, aggiungiamo un sistema di punteggio che aumenta ogni volta che un invader viene abbattuto. Il punteggio è già collegato nel codice che abbiamo scritto in precedenza, ma vediamo esattamente come funziona.

Il punteggio viene aggiornato ogni volta che un proiettile del giocatore colpisce un invader. Ogni volta che accade, il punteggio aumenta di 100 punti. Questo valore viene visualizzato sullo schermo attraverso l’elemento HTML con l’ID scoreElement.

Introduzione delle particelle per le esplosioni al colpo

Per dare al gioco una grafica più accattivante, aggiungiamo un effetto di esplosione sotto forma di particelle ogni volta che un invader viene abbattuto. Le particelle simuleranno i detriti dell’esplosione.

Aggiungi questo codice al tuo file index.js:

class Particle {
    constructor({ position, velocity, radius, color, fades }) {
        this.position = position;
        this.velocity = velocity;
        this.radius = radius;
        this.color = color;
        this.opacity = 1;
        this.fades = fades;
    }

    draw() {
        c.save();
        c.globalAlpha = this.opacity;
        c.beginPath();
        c.arc(this.position.x, this.position.y, this.radius, 0, Math.PI * 2);
        c.fillStyle = this.color;
        c.fill();
        c.closePath();
        c.restore();
    }

    update() {
        this.draw();
        this.position.x += this.velocity.x;
        this.position.y += this.velocity.y;

        if (this.fades) this.opacity -= 0.01;
    }
}

const particles = [];

function createParticles({ object, color, fades }) {
    for (let i = 0; i < 15; i++) {
        particles.push(
            new Particle({
                position: {
                    x: object.position.x + object.width / 2,
                    y: object.position.y + object.height / 2,
                },
                velocity: {
                    x: (Math.random() - 0.5) * 2,
                    y: (Math.random() - 0.5) * 2,
                },
                radius: Math.random() * 3,
                color: color || '#baa0de',
                fades,
            })
        );
    }
}

Cosa fa questo codice?

  1. Creare una particella (Particle): ogni particella è rappresentata da un piccolo cerchio che ha una posizione, una velocità, un raggio (dimensione), un colore e un’opacità.
  2. Disegnare la particella (draw): questa funzione disegna la particella sul canvas. Se fades è vero, l’opacità della particella diminuisce nel tempo, facendola svanire.
  3. Aggiornare la posizione (update): la particella si muove in base alla sua velocità. Se l’opacità della particella è inferiore a un certo valore, la particella svanisce gradualmente.
  4. Creare un esplosione di particelle (createParticles): questa funzione crea un gruppo di particelle ogni volta che viene chiamata, simulando un’esplosione.

Integrazione delle particelle nella Funzione animate

Per far sì che le particelle appaiano quando un invader viene abbattuto, dobbiamo integrare le particelle nella funzione animate.

Modifica la funzione animate in questo modo:

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

    player.update();

    particles.forEach((particle, i) => {
        if (particle.opacity <= 0) {
            setTimeout(() => {
                particles.splice(i, 1);
            }, 0);
        } else {
            particle.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();
        }

        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';
            }, 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 delle particelle (particles.forEach): Ogni particella viene aggiornata in base alla sua velocità. Se la sua opacità è scesa a zero, viene rimossa dall’array.
  2. Esplosioni: Ogni volta che un invader viene abbattuto, viene creata un’esplosione di particelle. Queste particelle si muovono e svaniscono, creando un effetto visivo.
  3. Fine del gioco: Se la navicella del giocatore viene colpita, viene generata un’esplosione di particelle bianche, e il gioco termina con il messaggio “GAME OVER”.

Adesso il tuo Space Invaders è completo. Ma c’è ancora qualche dettaglio che possiamo rifinire per renderlo ancora più coinvolgente. Curioso? Corri al prossimo capitolo! 

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