I fjor viste jeg deg hvordan du lager et skytespill med Flash og AS3. Med HTML5s økning i popularitet (og evner), la oss se på hvordan du gjør det samme med HTML5, JavaScript og EaselJS.
La oss se på det endelige resultatet vi vil jobbe for:
Klikk for å spille demoen.
Ved å bruke pre-made sprites vil vi kode en underholdende Space Shooter spill i HTML5 ved hjelp av EaselJS-biblioteket.
Spilleren vil kunne styre et romskip og skyte flere fiender mens du reiser i rommet.
Et enkelt og futuristisk grensesnitt vil bli brukt, dette innebærer bitmaps og mer. Jeg har brukt et flott sprite-bibliotek i demonstrasjonen av denne opplæringen, disse er en del av den gratis Sinistar Clone Graphics.
Grensesnittressursene som kreves for denne opplæringen finner du i vedlagte nedlastning.
EaselJS biblioteket vil bli brukt til å bygge vårt spill, sørg for at du leser Starter opplæringsprogram hvis du er ny på dette biblioteket.
Du kan laste ned EaselJS fra sitt offisielle nettsted.
La oss forberede vårt HTML-dokument, det er en enkel HTML-struktur for å begynne å skrive vår app. Lagre dette som Shooter.html
.
shooter
La oss legge til litt CSS også, denne linjen vil fjerne standard høydepunktet når du klikker på et element ved hjelp av en mobil nettleser; uten dette vil mobilopplevelsen reduseres drastisk.
shooter
Følgende kode legger til nødvendige JavaScript-biblioteker som kreves for at appen skal kunne fungere.
shooter
Main.js
er filen vi vil bruke til å lagre alle våre egne funksjoner for spillet. Lag det nå og lagre det i samme mappe som Shooter.html
. Du må også laste ned EaselJS-bibliotekene som er oppført.
I de neste linjene kaller vi vår hovedfunksjon; Dette er funksjonen som vil starte applikasjonen vår, den blir opprettet senere i vår JavaScript-kode.
shooter
Lerret er lagt til i denne linjen. Vi tilordner en ID for å referere den senere og også sette bredde og høyde.
shooter
La oss starte vår spillopprettelse!
Åpne din foretrukne JavaScript-editor (noen tekstredigerer vil fungere, men du vil ikke ha syntaxutheving) og forberede deg til å skrive ditt fantastiske spill. Åpne Main.js
fil du opprettet tidligere.
Vi starter med å definere alle grafiske og logiske variabler.
De neste variablene representerer HTML-lerretelementet og scenen som vil bli knyttet til den. (De scene variabel vil oppføre seg på samme måte som scenen i et AS3 Flash-prosjekt.)
/ * Definer lærred * / var lerret; var scenen;
De neste variablene lagrer bakgrunnsbildene. To flislagt bilder brukes til å lage en uendelig rullende bakgrunn.
/ * Bakgrunn * / var bgImg = nytt bilde (); var bg; var bg2Img = nytt bilde (); var bg2;
Dette er skipet som vil bli brukt som spillerkarakter eller -helte.
/ * Ship * / var sImg = nytt bilde (); var skipet;
Flere fiender vil være på scenen; De vil bruke dette som kilde grafikk.
/ * Enemy * / var eImg = nytt bilde ();
En sjef vil være til stede i spillet, større og med mer helse enn de andre fiender. Disse variablene brukes til å instantiere det.
/ * Boss * / var bImg = nytt bilde (); var sjef;
"Livet" -ikonet. Tre liv er gitt i begynnelsen, og du mister en når en fiende rammer.
/ * Bor * / var lImg = nytt bilde ();
Dette er ditt våpen: brannkuler på fiender for å drepe dem. Denne variabelen lagrer kildebildet.
/ * Bullets * / var bltImg = nytt bilde ();
To varsler brukes i spillet, en for når du vinner og en for når du taper. Vi ser hvordan du bestemmer en seier eller et tap senere i denne opplæringen.
/ * Alert * / var winImg = nytt bilde (); var loseImg = nytt bilde (); var vinne; var miste;
Dette er variablene vi skal bruke, les kommentarene i koden for å få vite mer om dem. Noen av navnene deres er selvforklarende og har ingen kommentarer.
var liv = ny Container (); // lagrer livene gfx var bullets = new Container (); // lagrer kulene gfx var fiender = ny Container (); // lagrer fiender gfx var bossHelse = 20; var score; var gfxLoaded = 0; // brukes som en forhåndslaster, teller de allerede lastede elementene var centerX = 160; var centerY = 240; var tkr = nytt objekt (); // brukes som Ticker listener var timerSource; // refererer til en setInterval-metode
Vi bruker lydeffekter for å forbedre følelsen av spillet. Du kan finne lydene som brukes i dette eksemplet på Soungle.com ved hjelp av søkeordene rom, eksplosjon og laser.
De Hoved()
funksjonen vil være den første som skal utføres når nettsiden er lastet, fordi den er referert til i på Last
attributten til HTML-dokumentet (se trinn 7).
Det kaller de nødvendige funksjonene for å starte spillet. Vi lager disse funksjonene i de neste trinnene - alt fra trinn 19 til trinn 23 skal gå inn i denne funksjonen.
funksjon Hoved () // kode ...
Denne koden får HTML-lerret-IDen og kobler den til klassen EaselJS Stage. Dette gjør at scenevarianten oppfører seg som sceneklassen i AS3.
/ * Link Canvas * / canvas = document.getElementById ('Shooter'); scene = nytt scenen (lerret);
Mus Hendelser er deaktivert som standard i EaselJS for å forbedre ytelsen; som vi trenger i spillet legger vi til følgende linje.
stage.mouseEventsEnabled = true;
Vi bruker SoundJS for å legge til lyder i vårt spill. SoundJS s addBatch
Metoden bruker en rekke tre parametre for hver samtale:
Navn
: Eksempelnavnet du vil ha lyden til å ha - dette vil bli brukt til å spille av lyden senere.src
: URL til lydfilen.forekomster
: Antall forekomster som kan spilles samtidig./ * Lyd * / SoundJS.addBatch ([navn: 'sjef', src: 'boss.mp3', forekomster: 1, navn: 'explode', src: 'explode.mp3', forekomster: 10 navn: 'shot', src: 'shot.mp3', forekomster: 10]);
Denne koden brukes til å forhåndsinstallere grafikken ved hjelp av en funksjon som vi skal skrive senere. Den peker hvert bildeobjekt som vi opprettet før til kilden PNG-filen i dokumentmappen vår. Et navn er gitt for å oppdage hvilket bilde som er lastet, og til slutt blir funksjonen som håndterer de lastede bildene, kalt.
/ * Legg inn 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 = 'skip'; sImg.onload = loadGfx; eImg.src = 'enemy1.png'; eImg.name = 'fiende'; eImg.onload = loadGfx; bImg.src = 'boss.png'; bImg.name = 'sjef'; 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 = 'win'; winImg.onload = loadGfx; loseImg.src = 'lose.png'; loseImg.name = 'lose'; loseImg.onload = loadGfx;
Ticker-klassen gir en sentralisert "tick", kringkastes med et bestemt intervall. Vi kan bruke det sett kryss()
Fungerer for å kjøre bestemt kode med jevn frekvens.
Følgende kode angir bildefrekvensen til 30 og definerer scenen som lytteren til flåttene.
TweenJS-klassen vil lytte til dette krysset for å utføre animasjonene.
/ * Ticker * / Ticker.setFPS (30); Ticker.addListener (trinn);
Hver gang en grafikk er lastet, kjører denne funksjonen. Det vil tilordne hvert bilde til en bitmap-objekt og kontrollere at alle elementene lastes inn før du fortsetter å ringe addGameView
.
funksjon b hvis (e.target.name = 'skip') skip = ny Bitmap (sImg); gfxLoaded ++; hvis (gfxLoaded == 9) addGameView ();
Når alle grafikkene er lastet på addGameView
funksjon kalles. Denne funksjonen vil legge til skipet, livscounter, score og bakgrunn til scenen.
funksjon addGameView () ship.x = centerX - 18.5; ship.y = 480 + 34; / * Legg til liv * / for (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);
Spillerens skip vil være musekontrollert, og vi bruker denne funksjonen til å håndtere det:
funksjon flytteskip (e) ship.x = e.stageX - 18.5;
e.stageX
refererer til musens x-koordinat, og denne funksjonen kalles når musen flyttes.
Vårt skip vil kunne skyte kuler for å ødelegge og beskytte seg mot fiender. Denne funksjonen løper hver gang brukeren klikker scenen og vil plassere en kule foran skipet som senere flyttes av Oppdater()
funksjon. Det spiller også en skytelyd.
funksjonsskyting () var b = ny Bitmap (bltImg); b.x = ship.x + 13; b.y = ship.y - 20; bullets.addChild (b); stage.update (); SoundJS.play ( 'skudd');
Det ville ikke være en skytter uten noe å skyte. Her en setInterval ()
brukes til å lage en fiende hver 1000 millisekunder (du kan endre verdien i neste trinn) som senere flyttes av Oppdater()
funksjon.
funksjon addEnemy () var e = ny Bitmap (eImg); e.x = Math.floor (Math.random () * (320 - 50)) e.y = -50 enemies.addChild (e); stage.update ();
Disse linjene vil legge til de nødvendige lytterne til scenen og timeren; Dette inkluderer musebegivenheter, tidsbegrensede hendelser (via setInterval
) og Ticker-hendelser som vil oppdatere spillet hver ramme.
funksjon startGame () stage.onMouseMove = moveShip; bg.onPress = shoot; bg2.onPress = shoot; Ticker.addListener (tkr, false); tkr.tick = update; timerSource = setInterval ('addEnemy ()', 1000);
Bakgrunnen flyttes hver ramme for å simulere romreise; når den nedre bakgrunnsspriten når scenegrensen, flyttes den tilbake til toppen, og skaper en uendelig sløyfe.
funksjonsoppdatering () / * Flytt bakgrunn * / bg.y + = 5; bg2.y + = 5; hvis (bg.y> = 480) bg.y = -480; ellers hvis (bg2.y> = 480) bg2.y = -480;
De neste kodelinjene sjekker om det er kuler i scenen; I så fall flyttes kulene oppover.
/ * Flytt kuler * / for (var i = 0; jeg < bullets.children.length; i++) bullets.children[i].y -= 10;
La oss legge til noen linjer for å oppdage kuleposisjonen, og bruk dette til å ødelegge en kule når den ikke lenger er synlig.
/ * Flytt kuler * / for (var i = 0; jeg < bullets.children.length; i++) bullets.children[i].y -= 10; /* Remove Offstage Bullets */ if(bullets.children[i].y < - 20) bullets.removeChildAt(i);
Vi legger til en stor dårlig sjef i spillet. Når brukeren når en bestemt score, vil sjefen vises:
/ * Vis Boss * / hvis (parseInt (score.text)> = 500 && boss == null) boss = nytt Bitmap (bImg); SoundJS.play ( 'boss'); boss.x = centerX - 90; boss.y = -183; stage.addChild (boss); Tween.get (sjef) .to (y: 40, 2000) // mellom sjefen på spillområdet
Fiender, som kulene, flyttes også hver ramme. Denne koden finner alle fiender i scenen ved hjelp av fiender
container, og beveger dem hver 5px nedover.
/ * Flytt fiendene * / for (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5;
Vi kontrollerer også fiendernes posisjoner for å ødelegge dem når de ikke lenger er synlige.
/ * Flytt fiendene * / for (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5; /* Remove Offstage Enemies */ if(enemies.children[j].y > 480 + 50) enemies.removeChildAt (j);
Kulene i beholderen blir testet for kollisjon med fiender; Når dette skjer, blir begge fjernet fra scenen, en lyd spilles og poengsummen er oppdatert.
for (var k = 0; k < bullets.children.length; k++) /* Bullet - Enemy Collision */ if(bullets.children[k].x >= enemies.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);
Følgende kode håndterer sjefskollisjonene, den bruker den samme metoden som brukes i bullet-fiendens kollisjonssløp. Her bruker vi bossHealth
variabel for å bestemme når sjefen er beseiret.
/ * Bullet - Boss Collision * / hvis (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);
Her ser vi om en fiende kolliderer med spillerens skip; hvis det gjøres, spilles en lyd, et liv fjernes, og skipet er animert.
/ * Ship - Enemy Collision * / hvis (enemies.hitTest (ship.x, ship.y) || enemies.hitTest (ship.x + 37, ship.y)) enemies.removeChildAt (j); lives.removeChildAt (lives.length); ship.y = 480 + 34; Tween.get (skip) .to (y: 425, 500) SoundJS.play ('explo');
Spilleren vinner når sjefen mister all sin helse og taper hvis alle sine egne liv går tapt. De neste linjene oppdager disse situasjonene og kaller en varslingsfunksjon ved hjelp av riktig parameter.
/ * Check for win * / if (boss! = Null && bossHealth <= 0) alert('win'); /* Check for lose */ if(lives.children.length <= 0) alert('lose');
Alerten viser spillerens informasjon om statusen til spillet; Det vises når en spillhendelse er nådd. Det fjerner spillelytterne og viser passende beskjed.
funksjonalarm (e) / * Fjern lyttere * / stage.onMouseMove = null; bg.onPress = null; bg2.onPress = null; Ticker.removeListener (TKR); tkr = null; timerSource = null; / * Vis riktig melding * / hvis (e == 'vinn') win = new Bitmap (winImg); win.x = centerX - 64; win.y = centerY - 23; stage.addChild (Win); scene.removeChild (fiender, sjef); else lose = new Bitmap (loseImg); lose.x = centerX - 64; lose.y = centerY - 23; stage.addChild (tape); stage.removeChild (fiender, skip); bg.onPress = funksjon () window.location.reload ();; bg2.onPress = function () window.location.reload ();; stage.update ();
Lagre arbeidet ditt (hvis du ikke har det) og åpne HTML-filen i nettleseren for å se HTML5-spillet ditt!
Du har lært hvordan du lager et Space Shooter-spill med alle de grunnleggende funksjonene, prøv å utvide det med det du allerede vet. En god start ville gjøre fiender eller sjef skyte tilbake på spilleren.
Jeg håper du likte denne opplæringen, takk for å lese!