L'anno scorso, ti ho mostrato come creare un gioco shoot-'-up con Flash e AS3. Con l'aumento della popolarità (e delle capacità) di HTML5, diamo un'occhiata a come fare lo stesso con HTML5, JavaScript e EaselJS.
Diamo un'occhiata al risultato finale su cui lavoreremo:
Clicca per riprodurre la demo.
Usando gli sprite prefabbricati, codificheremo un divertente Sparatutto spaziale gioco in HTML5 usando la libreria EaselJS.
Il giocatore sarà in grado di controllare un'astronave e sparare a più nemici mentre viaggia nello spazio.
Verrà utilizzata un'interfaccia semplice e futuristica, che include bitmap e altro ancora. Ho usato una grande libreria di sprite nella demo di questo tutorial, questi sono parte della Sinistar Clone Graphics gratuita.
Le risorse dell'interfaccia richieste per questo tutorial sono disponibili nel download allegato.
La libreria EaselJS verrà utilizzata per costruire il nostro gioco, assicurati di leggere il Iniziare tutorial se sei nuovo in questa libreria.
È possibile scaricare EaselJS dal suo sito Web ufficiale.
Prepariamo il nostro documento HTML, è una semplice struttura HTML per iniziare a scrivere la nostra app. Salva questo come Shooter.html
.
tiratore
Aggiungiamo anche un po 'di CSS, questa linea rimuoverà l'evidenziazione predefinita quando tocchi un elemento usando un browser mobile; senza questo, l'esperienza mobile diminuirebbe drasticamente.
tiratore
Il codice seguente aggiunge le librerie JavaScript necessarie per il funzionamento della nostra app.
tiratore
main.js
è il file che useremo per memorizzare tutte le nostre funzioni per il gioco. Crealo ora e salvalo nella stessa cartella di Shooter.html
. Dovrai anche scaricare le librerie EaselJS elencate.
Nelle righe successive chiamiamo la nostra funzione principale; questa è la funzione che avvierà la nostra applicazione, verrà creata successivamente nel nostro codice JavaScript.
tiratore
La tela viene aggiunta in questa linea. Assegniamo un ID per farvi riferimento più tardi e impostarne anche la larghezza e l'altezza.
tiratore
Iniziamo la nostra creazione del gioco!
Apri l'editor JavaScript preferito (qualsiasi editor di testo funzionerà, ma non avrai l'evidenziazione della sintassi) e preparati a scrivere il tuo fantastico gioco. Apri il main.js
file creato in precedenza.
Inizieremo definendo tutte le variabili grafiche e logiche.
Le successive variabili rappresentano l'elemento canvas HTML e lo stage che sarà collegato ad esso. (Il palcoscenico la variabile si comporterà in modo simile allo stage in un progetto AS3 Flash.)
/ * Definisci canvas * / var canvas; palco var;
Le successive variabili memorizzano le immagini di sfondo. Vengono utilizzate due immagini affiancate per creare uno sfondo a scorrimento infinito.
/ * Sfondo * / var bgImg = nuova immagine (); var bg; var bg2Img = new Image (); var bg2;
Questa è la nave che verrà utilizzata come personaggio o eroe del giocatore.
/ * Spedisci * / var sImg = new Image (); nave var;
Più nemici saranno sul palco; useranno questo come il grafico di origine.
/ * Enemy * / var eImg = new Image ();
Un boss sarà presente nel gioco, più grande e con più salute degli altri nemici. Queste variabili sono usate per istanziarlo.
/ * Boss * / var bImg = new Image (); capo var;
L'icona "vita". All'inizio vengono date tre vite e ne perdi una quando colpite da un nemico.
/ * Lives * / var lImg = new Image ();
Questa è la tua arma: proiettili di fuoco contro i nemici per ucciderli. Questa variabile memorizza l'immagine sorgente.
/ * Bullets * / var bltImg = new Image ();
Nel gioco vengono usati due avvisi, uno per quando vinci e uno per quando perdi. Vedremo come determinare una vittoria o una perdita più avanti in questo tutorial.
/ * Alert * / var winImg = new Image (); var loseImg = new Image (); var vince; var perdere;
Queste sono le variabili che useremo, leggere i commenti nel codice per saperne di più su di loro. Alcuni dei loro nomi sono auto-esplicativi e quindi non hanno commenti.
var lives = new Container (); // memorizza le vite gfx var bullet = new Container (); // memorizza i proiettili gfx var enemy = new Container (); // memorizza i nemici gfx var bossHealth = 20; punteggio var; var gfxLoaded = 0; // usato come preloader, conta gli elementi già caricati var centerX = 160; var centerY = 240; var tkr = new Object (); // usato come listener ticker var timerSource; // fa riferimento a un metodo setInterval
Useremo effetti sonori per migliorare la sensazione del gioco. Puoi trovare i suoni usati in questo esempio su Soungle.com usando le parole chiave spazio, esplosione e laser.
Il Principale()
la funzione sarà la prima ad essere eseguita quando la pagina web viene caricata, perché viene indicata nel file onload
attributo del documento HTML (vedi passaggio 7).
Chiama le funzioni necessarie per iniziare il gioco. Creeremo tali funzioni nei passaggi successivi: tutto, dal passaggio 19 al passaggio 23, dovrebbe rientrare in questa funzione.
function Main () // code ...
Questo codice ottiene l'ID canvas HTML e lo collega alla classe Stage di EaselJS. Questo farà sì che la variabile stage si comporti come la stage class di AS3.
/ * Link Canvas * / canvas = document.getElementById ('Shooter'); stage = new Stage (canvas);
Gli eventi mouse sono disabilitati per impostazione predefinita in EaselJS per migliorare le prestazioni; come abbiamo bisogno di quelli nel gioco, aggiungiamo la seguente riga.
stage.mouseEventsEnabled = true;
Useremo SoundJS per aggiungere suoni al nostro gioco. SoundJS di addBatch
metodo utilizza una matrice di tre parametri per ogni chiamata:
nome
: Il nome dell'istanza che vuoi che abbia il suono - questo sarà usato per riprodurre il suono in un secondo momento.src
: L'URL del file audio.casi
: Il numero di istanze che possono essere riprodotte contemporaneamente./ * Sound * / SoundJS.addBatch ([nome: 'boss', src: 'boss.mp3', istanze: 1, nome: 'explo', src: 'explo.mp3', istanze: 10, nome: 'shot', src: 'shot.mp3', istanze: 10]);
Questo codice è usato per precaricare la grafica con l'aiuto di una funzione che scriveremo in seguito. Punta ogni oggetto Image che abbiamo creato prima al file PNG sorgente nella nostra cartella documenti. Viene dato un nome per rilevare quale immagine viene caricata e infine viene chiamata la funzione che gestisce le immagini caricate.
/ * Carica GFX * / bgImg.src = 'bg.png'; bgImg.name = 'bg'; bgImg.onload = loadGfx; bg2Img.src = 'bg2.png'; bg2Img.name = 'bg2'; bg2Img.onload = loadGfx; sImg.src = 'ship.png'; sImg.name = 'nave'; sImg.onload = loadGfx; eImg.src = 'enemy1.png'; eImg.name = 'nemico'; eImg.onload = loadGfx; bImg.src = 'boss.png'; bImg.name = 'boss'; bImg.onload = loadGfx; lImg.src = 'live.png'; lImg.name = 'live'; lImg.onload = loadGfx; bltImg.src = 'bullet.png'; bltImg.name = 'bullet'; bltImg.onload = loadGfx; winImg.src = 'win.png'; winImg.name = 'vinci'; winImg.onload = loadGfx; loseImg.src = 'lose.png'; loseImg.name = 'perdere'; loseImg.onload = loadGfx;
La classe Ticker fornisce un "tick" centralizzato, trasmesso a intervalli regolari. Possiamo usare il suo tick ()
funzione per eseguire determinati codici a frequenza regolare.
Il codice seguente imposta il frame rate su 30 e definisce lo stage come listener per i tick.
La classe TweenJS ascolterà questo segno di spunta per eseguire le animazioni.
/ * Ticker * / Ticker.setFPS (30); Ticker.addListener (fase);
Ogni volta che viene caricato un grafico, questa funzione verrà eseguita. Assegna ogni immagine a un oggetto bitmap e controlla che tutti gli elementi siano caricati prima di procedere alla chiamata addGameView
.
function loadGfx (e) if (e.target.name = 'bg') bg = new Bitmap (bgImg); if (e.target.name = 'bg2') bg2 = new Bitmap (bg2Img); if (e.target.name = 'ship') ship = new Bitmap (sImg); gfxLoaded ++; if (gfxLoaded == 9) addGameView ();
Quando sono caricati tutti i grafici addGameView
la funzione è chiamata. Questa funzione aggiungerà la nave, il contatore delle vite, il punteggio e gli sfondi sul palco.
function addGameView () ship.x = centerX - 18,5; ship.y = 480 + 34; / * Aggiungi vite * / per (var i = 0; i < 3; i++) var l = new Bitmap(lImg); l.x = 248 + (25 * i); l.y = 463; lives.addChild(l); stage.update(); /* Score Text */ score = new Text('0', 'bold 14px Courier New', '#FFFFFF'); score.maxWidth = 1000; //fix for Chrome 17 score.x = 2; score.y = 476; /* Second Background */ bg2.y = -480; /* Add gfx to stage and Tween Ship */ stage.addChild(bg, bg2, ship, enemies, bullets, lives, score); Tween.get(ship).to(y:425, 1000).call(startGame);
La nave del giocatore sarà controllata dal mouse, e usiamo questa funzione per gestire quello:
function moveShip (e) ship.x = e.stageX - 18.5;
e.stageX
si riferisce alla coordinata x del mouse e questa funzione viene chiamata ogni volta che il mouse si sposta.
La nostra nave sarà in grado di sparare proiettili per distruggere e proteggersi dai nemici. Questa funzione verrà eseguita ogni volta che l'utente fa clic sul palco e posizionerà un proiettile davanti alla nave che verrà successivamente spostato dal aggiornare()
funzione. Riproduce anche un suono di ripresa.
function shoot () var b = new Bitmap (bltImg); b.x = ship.x + 13; b.y = ship.y - 20; bullets.addChild (b); stage.update (); SoundJS.play ( 'colpo');
Non sarebbe uno sparatutto senza qualcosa da sparare. Qui, a setInterval ()
è usato per creare un nemico ogni 1000 millisecondi (puoi cambiare quel valore nel passaggio successivo) che viene successivamente spostato dal aggiornare()
funzione.
function addEnemy () var e = new Bitmap (eImg); e.x = Math.floor (Math.random () * (320 - 50)) e.y = -50 enemy.addChild (e); stage.update ();
Queste linee aggiungeranno gli ascoltatori necessari allo stage e al timer; questo include eventi mouse, eventi a tempo (via setInterval
) e gli eventi Ticker che aggiorneranno il gioco ogni fotogramma.
function startGame () stage.onMouseMove = moveShip; bg.onPress = sparare; bg2.onPress = sparare; Ticker.addListener (tkr, false); tkr.tick = aggiornamento; timerSource = setInterval ('addEnemy ()', 1000);
Lo sfondo viene spostato su ogni fotogramma per simulare il viaggio nello spazio; quando lo sprite di sfondo inferiore raggiunge il limite dello stage viene spostato in alto, creando un loop infinito.
function update () / * Sposta sfondo * / bg.y + = 5; bg2.y + = 5; if (bg.y> = 480) bg.y = -480; else if (bg2.y> = 480) bg2.y = -480;
Le prossime righe di codice controllano se ci sono proiettili in scena; se è così, i proiettili sono spostati verso l'alto.
/ * Sposta puntini * / per (var i = 0; i < bullets.children.length; i++) bullets.children[i].y -= 10;
Aggiungiamo alcune linee per rilevare la posizione del proiettile e usiamola per distruggere un proiettile quando non è più visibile.
/ * Sposta puntini * / per (var i = 0; i < bullets.children.length; i++) bullets.children[i].y -= 10; /* Remove Offstage Bullets */ if(bullets.children[i].y < - 20) bullets.removeChildAt(i);
Aggiungiamo un grande capo cattivo al gioco. Quando l'utente raggiunge un determinato punteggio, apparirà il boss:
/ * Mostra Boss * / if (parseInt (score.text)> = 500 && boss == null) boss = new Bitmap (bImg); SoundJS.play ( 'capo'); boss.x = centerX - 90; boss.y = -183; stage.addChild (sporgenza); Tween.get (boss) .to (y: 40, 2000) // interpolazione del boss nell'area di gioco
Anche i nemici, come i proiettili, vengono spostati su ogni fotogramma. Questo codice trova tutti i nemici nella scena usando il nemici
contenitore, e li sposta ogni 5 px verso il basso.
/ * Muovi i nemici * / per (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5;
Controlliamo anche le posizioni dei nemici per distruggerli quando non sono più visibili.
/ * Muovi i nemici * / per (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5; /* Remove Offstage Enemies */ if(enemies.children[j].y > 480 + 50) enemy.removeChildAt (j);
I proiettili nel contenitore sono testati per la collisione con i nemici; quando ciò accade, entrambi vengono rimossi dallo stage, viene riprodotto un suono e il punteggio viene aggiornato.
per (var k = 0; k < bullets.children.length; k++) /* Bullet - Enemy Collision */ if(bullets.children[k].x >= enemy.children [j] .x && bullets.children [k] .x + 11 < enemies.children[j].x + 49 && bullets.children[k].y < enemies.children[j].y + 40) bullets.removeChildAt(k); enemies.removeChildAt(j); stage.update(); SoundJS.play('explo'); score.text = parseFloat(score.text + 50);
Il seguente codice gestisce le collisioni del boss, utilizza lo stesso metodo utilizzato nel ciclo di collisione nemico-proiettile. Qui usiamo il bossHealth
variabile per determinare quando il boss è sconfitto.
/ * Bullet - Boss Collision * / if (boss! = Null && bullets.children [k] .x> = boss.x && bullets.children [k] .x + 11 < boss.x + 183 && bullets.children[k].y < boss.y + 162) bullets.removeChildAt(k); bossHealth--; stage.update(); SoundJS.play('explo'); score.text = parseInt(score.text + 50);
Qui controlliamo se un nemico si scontra con la nave del giocatore; se lo fa, viene riprodotto un suono, viene rimossa una vita e la nave viene animata.
/ * Ship - Enemy Collision * / if (enemy.hitTest (ship.x, ship.y) || enemy.hitTest (ship.x + 37, ship.y)) enemy.removeChildAt (j); lives.removeChildAt (lives.length); ship.y = 480 + 34; Tween.get (ship) .to (y: 425, 500) SoundJS.play ('explo');
Il giocatore vince quando il capo perde tutta la sua salute e perde se tutte le sue vite sono perse. Le righe successive rilevano quelle situazioni e chiamano una funzione di avviso usando il parametro corretto.
/ * Verifica la vincita * / se (boss! = Null && bossHealth <= 0) alert('win'); /* Check for lose */ if(lives.children.length <= 0) alert('lose');
L'avviso mostra le informazioni del giocatore sullo stato del gioco; viene mostrato quando viene raggiunto un evento di gioco. Rimuove gli ascoltatori del gioco e mostra il messaggio appropriato.
funzione alert (e) / * Remove Listeners * / stage.onMouseMove = null; bg.onPress = null; bg2.onPress = null; Ticker.removeListener (TKR); tkr = null; timerSource = null; / * Visualizza messaggio corretto * / if (e == 'vinci') win = new Bitmap (winImg); win.x = centerX - 64; win.y = centerY - 23; stage.addChild (vittoria); stage.removeChild (nemici, boss); else lose = new Bitmap (loseImg); lose.x = centerX - 64; lose.y = centerY - 23; stage.addChild (perdere); stage.removeChild (nemici, nave); bg.onPress = function () window.location.reload ();; bg2.onPress = function () window.location.reload ();; stage.update ();
Salva il tuo lavoro (se non lo hai) e apri il file HTML nel browser per vedere come funziona il tuo gioco HTML5!
Hai imparato come creare un gioco Space Shooter con tutte le sue caratteristiche di base, prova ad estenderlo usando ciò che già sai. Un buon inizio sarebbe far sparare i nemici o il boss al giocatore.
Spero che questo tutorial ti sia piaciuto, grazie per la lettura!