
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…


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?
- 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à.
- Disegnare la particella (draw): questa funzione disegna la particella sul canvas. Se fades è vero, l’opacità della particella diminuisce nel tempo, facendola svanire.
- 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.
- 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?
- 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.
- Esplosioni: Ogni volta che un invader viene abbattuto, viene creata un’esplosione di particelle. Queste particelle si muovono e svaniscono, creando un effetto visivo.
- 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!
CONTENUTI GRATUITI IN EVIDENZA
Guide per aspiranti programmatori 👨🏻🚀
Vuoi muovere i primi passi nel Digital e Tech? Abbiamo preparato alcune guide per aiutarti a orientarti negli ambiti più richiesti oggi.