Abbiamo visto come generare gli oggetti e come animarli e disporli sulla scena, ma che divertimento possiamo trarne se i nostri proiettili trapassano il nemico e viceversa? Naturalmente serve gestire le collisioni! Creiamo allora una funzione gestisci_collisioni
che accetti in ingresso un array di oggetti ed uno di spari:
function gestisci_collisioni(oggetti, spari) {
_.each(oggetti, function(oggetto) {
_.each(spari, function(sparo) {
if( Math.abs( oggetto.x - sparo.x ) < sparo.spriteSheet._frameWidth
&& Math.abs( oggetto.y - sparo.y ) < sparo.spriteSheet._frameHeight)
{
oggetto.direction = 0;
oggetto.gotoAndPlay('boom');
spari = _.without(spari, sparo);
stage.removeChild(sparo);
}
})
})
}
Se la distanza fra le posizioni di ogni coppia (oggetto, sparo) risulta inferiore alla dimensione dei due sprite siamo in presenza di una collisione: a questo punto dobbiamo eseguire l'animazione boom
sull'oggetto e rimuovere il proiettile incriminato dalla scena e dall'array corrispondente.
Implementiamo la chiamata a gestisci_collisioni
nella 'sezione aggiornamento oggetti'
sia per gli aerei nemici nei confronti dei proiettili amici sia per i proiettili lanciati dagli aerei nemici nei confronti dell'aereo pilotato dall'utente:
gestisci_collisioni([aereo], spari_nemici);
gestisci_collisioni(nemici, aereo.spari);
Eseguiamo il tutto nel browser e vediamo che ora i nemici esplodono al contatto coi nostri proiettili:
Ma cosa succede quando è il nostro aereo ad essere colpito? Certo, viene eseguita l'animazione di esplosione ma poi nulla ci vieta di continuare a giocare e sparare ai nemici in quanto tutta la logica del gioco resta perfettamente valida! Per porre rimedio a questo dobbiamo introdurre lo stato di 'game over' in coda alla sequenza di esplosione del nostro mezzo.
Game over
Per prima cosa agganciamo una funzione di callback all'aereo, aggiungiamo nella 'sezione di aggiunta allo stage'
:
aereo.onAnimationEnd= animazione_aereo;
Nella funzione animazione_aereo
dobbiamo controllare soltanto che sia completa l'esecuzione della sequenza boom
e, in caso affermativo, visualizzare a schermo la scritta 'GAME OVER' con il punteggio delle uccisioni, poi fermare il gioco. Ecco la funzione da aggiungere a 1945.js
:
function animazione_aereo(ae) {
switch(ae.currentAnimation) {
case 'boom':
stage.removeChild(ae);
var game_over = new Text("GAME OVER, " + nemici_uccisi + " kills" , '30px Courier');
game_over.x = (w - game_over.getMeasuredWidth())/2;
game_over.y = h/2;
stage.addChild(game_over);
tick();
Ticker.setPaused(true);
break;
}
}
Le ultime due istruzioni di questa funzione forzano la chiamata alla routine di disegno tick
per accertarsi che la scritta venga correttamente mostrata e poi mettano in pausa il motore di easel.js sospendendo a tutti gli effetti il gioco.
Aggiungere lo sfondo
Per completare aggiungiamo uno sfondo al canvas, modificando il CSS all'interno di index.html:
canvas{
display: block;
margin: 0px auto;
background: url('sprites/background.png');
border: 5px solid rgb(0,53,85);
}
Lanciamo il tutto nel browser e gustiamoci il risultato delle nostre fatiche:
Conclusioni
Con i giusti strumenti scrivere videogiochi su canvas diventa un'esperienza non solo abbordabile, ma anche divertente e non priva di soddisfazioni. Easel.js si candida a pieni voti tra questi strumenti e ci consente, come abbiamo visto, di sviluppare progetti completi con poche ed eleganti righe di codice.