Vorig jaar heb ik je laten zien hoe je een shoot-'em-up-game kunt maken met Flash en AS3. Nu de populariteit en de mogelijkheden van HTML5 toenemen, laten we eens kijken hoe hetzelfde te doen met HTML5, JavaScript en EaselJS.
Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:
Klik om de demo af te spelen.
Met behulp van vooraf gemaakte sprites coderen we een vermakelijk Space Shooter spel in HTML5 met de Easel JS-bibliotheek.
De speler kan een ruimteschip besturen en meerdere vijanden schieten terwijl hij in de ruimte reist.
Er zal een eenvoudige en futuristische interface worden gebruikt, dit omvat bitmaps en meer. Ik heb een geweldige Sprite-bibliotheek gebruikt in de demo van deze tutorial, deze maken deel uit van de gratis Sinistar Clone Graphics.
De benodigde interfacemiddelen voor deze tutorial zijn te vinden in de bijgevoegde download.
De EaselJS-bibliotheek zal worden gebruikt om ons spel te bouwen, zorg ervoor dat je de Ermee beginnen zelfstudie als u nog niet bekend bent met deze bibliotheek.
Je kunt EaselJS downloaden van de officiële website.
Laten we ons HTML-document voorbereiden, het is een eenvoudige HTML-structuur om onze app te schrijven. Bewaar deze als Shooter.html
.
schutter
Laten we ook een beetje CSS toevoegen, deze regel verwijdert de standaardmarkering wanneer u op een element tikt met een mobiele browser; zonder dit zou de mobiele ervaring drastisch afnemen.
schutter
De volgende code voegt de nodige JavaScript-bibliotheken toe die nodig zijn om onze app te laten werken.
schutter
main.js
is het bestand dat we zullen gebruiken om al onze eigen functies voor het spel op te slaan. Maak het nu en sla het op in dezelfde map als Shooter.html
. U moet ook de genoemde EaselJS-bibliotheken downloaden.
In de volgende regels noemen we onze hoofdfunctie; dit is de functie waarmee onze applicatie wordt gestart, deze wordt later in onze JavaScript-code gemaakt.
schutter
Het canvas wordt in deze regel toegevoegd. We wijzen een ID toe om er later naar te verwijzen en stellen ook de breedte en hoogte ervan in.
schutter
Laten we beginnen met het maken van games!
Open de JavaScript-editor van uw voorkeur (elke teksteditor werkt, maar u hoeft geen syntax te markeren) en bereid u voor op het schrijven van uw geweldige game. Open de main.js
bestand dat u eerder hebt gemaakt.
We beginnen met het definiëren van alle grafische en logische variabelen.
De volgende variabelen vertegenwoordigen het HTML-canvaselement en de fase die eraan wordt gekoppeld. (De stadium variabele zal zich op dezelfde manier gedragen als de fase in een AS3 Flash-project.)
/ * Definieer Canvas * / var canvas; var stadium;
De volgende variabelen slaan de achtergrondafbeeldingen op. Twee betegelde afbeeldingen worden gebruikt om een oneindig scrollende achtergrond te creëren.
/ * Achtergrond * / var bgImg = new Image (); var bg; var bg2Img = new Image (); var bg2;
Dit is het schip dat zal worden gebruikt als het personage of de held van de speler.
/ * Verzenden * / var sImg = new Image (); var schip;
Meerdere vijanden zullen op het podium staan; ze gebruiken dit als de bronafbeelding.
/ * Enemy * / var eImg = new Image ();
Een baas zal aanwezig zijn in het spel, groter en met meer gezondheid dan de andere vijanden. Deze variabelen worden gebruikt om het te instantiëren.
/ * Boss * / var bImg = new Image (); var baas;
Het pictogram "leven". Drie levens worden aan het begin gegeven en je verliest er een wanneer je wordt geraakt door een vijand.
/ * Live * / var lImg = nieuw afbeelding ();
Dit is je wapen: vuur kogels af op de vijanden om ze te doden. Deze variabele slaat de bronafbeelding op.
/ * Opsommingstekens * / var bltImg = nieuw afbeelding ();
Er worden twee meldingen gebruikt in de game, één voor wanneer je wint en één voor wanneer je verliest. We zullen later in deze tutorial zien hoe u een winst of verlies kunt bepalen.
/ * Waarschuwing * / var winImg = new Image (); var loseImg = new Image (); var win; var verliezen;
Dit zijn de variabelen die we zullen gebruiken, lees de opmerkingen in de code om meer over hen te weten. Sommige van hun namen spreken voor zich en hebben dus geen opmerkingen.
var lives = new Container (); // slaat de levens op gfx var bullets = new Container (); // slaat de kogels op gfx var vijanden = nieuwe container (); // slaat de vijanden op gfx var bossHealth = 20; var score; var gfxLoaded = 0; // gebruikt als een preloader, telt de reeds geladen items var centerX = 160; var centerY = 240; var tkr = new Object (); // gebruikt als Ticker luisteraar var timerSource; // verwijst naar een setInterval-methode
We zullen geluidseffecten gebruiken om het gevoel van het spel te verbeteren. Je kunt de geluiden die in dit voorbeeld worden gebruikt op Soungle.com vinden met behulp van de sleutelwoorden ruimte, explosie en laser.
De Hoofd()
functie zal als eerste worden uitgevoerd wanneer de webpagina wordt geladen, omdat er naar wordt verwezen in de onload
kenmerk van het HTML-document (zie stap 7).
Het roept de nodige functies op om het spel te starten. We zullen deze functies in de volgende stappen creëren - alles van stap 19 tot en met stap 23 zou binnen deze functie moeten gaan.
function Main () // code ...
Deze code krijgt de HTML-canvas-ID en koppelt deze aan de EaselJS Stage-klasse. Hierdoor zal de stage-variabele zich gedragen als de stage-klasse in AS3.
/ * Link Canvas * / canvas = document.getElementById ('Shooter'); stage = nieuwe Stage (canvas);
Muisgebeurtenissen zijn standaard uitgeschakeld in EaselJS om de prestaties te verbeteren; omdat we die in het spel nodig hebben, voegen we de volgende regel toe.
stage.mouseEventsEnabled = true;
We gebruiken SoundJS om geluiden aan onze game toe te voegen. SoundJS's addBatch
methode gebruikt een array van drie parameters voor elke oproep:
naam
: De naam van het exemplaar dat u wilt dat het geluid heeft - dit wordt gebruikt om het geluid later weer te geven.src
: De URL van het geluidsbestand.instanties
: Het aantal exemplaren dat tegelijkertijd kan worden afgespeeld./ * Sound * / SoundJS.addBatch ([name: 'boss', src: 'boss.mp3', exemplaren: 1, name: 'explo', src: 'explo.mp3', exemplaren: 10, name: 'shot', src: 'shot.mp3', exemplaren: 10]);
Deze code wordt gebruikt om de afbeeldingen vooraf te laden met behulp van een functie die we later zullen schrijven. Het wijst elk afbeeldingsobject dat we eerder hebben gemaakt naar het bron-PNG-bestand in onze documentenmap. Er wordt een naam gegeven om te detecteren welke afbeelding is geladen en tot slot wordt de functie genoemd die de geladen afbeeldingen afhandelt.
/ * Laad 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 = 'verzenden'; sImg.onload = loadGfx; eImg.src = 'enemy1.png'; eImg.name = 'vijand'; eImg.onload = loadGfx; bImg.src = 'boss.png'; bImg.name = 'baas'; bImg.onload = loadGfx; lImg.src = 'live.png'; lImg.name = 'live'; lImg.onload = loadGfx; bltImg.src = 'bullet.png'; bltImg.name = 'opsommingsteken'; bltImg.onload = loadGfx; winImg.src = 'win.png'; winImg.name = 'win'; winImg.onload = loadGfx; loseImg.src = 'lose.png'; loseImg.name = 'verliezen'; loseImg.onload = loadGfx;
De Ticker-klasse biedt een gecentraliseerd "vinkje", uitgezonden met een ingesteld interval. We kunnen het gebruiken Kruis aan()
functie om bepaalde code op een normale frequentie uit te voeren.
De volgende code stelt de framesnelheid in op 30 en definieert de stage als de listener voor de ticks.
De TweenJS-klasse luistert naar deze teek om de animaties uit te voeren.
/ * Ticker * / Ticker.setFPS (30); Ticker.addListener (trap);
Elke keer dat een afbeelding wordt geladen, wordt deze functie uitgevoerd. Het zal elke afbeelding toewijzen aan een bitmap-object en controleren of alle elementen zijn geladen voordat u verdergaat met bellen addGameView
.
functie loadGfx (e) if (e.target.name = 'bg') bg = nieuwe Bitmap (bgImg); if (e.target.name = 'bg2') bg2 = nieuwe Bitmap (bg2Img); if (e.target.name = 'ship') ship = new Bitmap (sImg); gfxLoaded ++; if (gfxLoaded == 9) addGameView ();
Wanneer alle afbeeldingen zijn geladen, is de addGameView
functie wordt aangeroepen. Deze functie voegt het schip toe, leeft tegenaanval, score en achtergronden op het podium.
function addGameView () ship.x = centerX - 18.5; ship.y = 480 + 34; / * Levens toevoegen * / 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);
Het schip van de speler wordt muisgestuurd en we gebruiken deze functie om dat aan te pakken:
functie moveShip (e) ship.x = e.stageX - 18.5;
e.stageX
verwijst naar de x-coördinaat van de muis, en deze functie wordt elke keer dat de muis beweegt genoemd.
Ons schip zal kogels kunnen schieten om zichzelf te vernietigen en zichzelf tegen vijanden te beschermen. Deze functie wordt uitgevoerd telkens wanneer de gebruiker op het podium klikt en een kogel voor het schip plaatst die later door het platform wordt verplaatst bijwerken()
functie. Het speelt ook een schietgeluid.
function shoot () var b = new Bitmap (bltImg); b.x = ship.x + 13; b.y = ship.y - 20; bullets.addChild (b); stage.update (); SoundJS.play ( 'shot');
Het zou geen schutter zijn zonder iets om te schieten. Hier een setInterval ()
wordt gebruikt om elke 1000 milliseconden een vijand te creëren (u kunt die waarde in de volgende stap wijzigen) die later wordt verplaatst door de bijwerken()
functie.
function addEnemy () var e = nieuwe Bitmap (eImg); e.x = Math.floor (Math.random () * (320 - 50)) e.y = -50 enemies.addChild (e); stage.update ();
Deze lijnen zullen de nodige luisteraars toevoegen aan het podium en de timer; dit omvat muisgebeurtenissen, getimede gebeurtenissen (via setInterval
) en Ticker-evenementen die het spel elk frame zullen bijwerken.
function startGame () stage.onMouseMove = moveShip; bg.onPress = schieten; bg2.onPress = schieten; Ticker.addListener (tkr, false); tkr.tick = update; timerSource = setInterval ('addEnemy ()', 1000);
De achtergrond wordt elk frame verplaatst om ruimtevaart te simuleren; wanneer de onderste achtergrondsprite de stadiumlimiet bereikt, wordt deze terug naar de top verplaatst, waardoor een oneindige lus ontstaat.
functie-update () / * Verplaats Achtergrond * / bg.y + = 5; bg2.y + = 5; if (bg.y> = 480) bg.y = -480; else if (bg2.y> = 480) bg2.y = -480;
De volgende regels code controleren of er kogels in fase zijn; in dat geval worden de kogels naar boven verplaatst.
/ * Kogels verplaatsen * / for (var i = 0; i < bullets.children.length; i++) bullets.children[i].y -= 10;
Laten we wat lijnen toevoegen om de positie van de kogel te detecteren en deze gebruiken om een kogel te vernietigen wanneer deze niet meer zichtbaar is.
/ * Kogels verplaatsen * / for (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);
We voegen een grote slechte baas toe aan het spel. Wanneer de gebruiker een bepaalde score bereikt, verschijnt de baas:
/ * Show Boss * / if (parseInt (score.text)> = 500 && boss == null) boss = new Bitmap (bImg); SoundJS.play (boss); boss.x = centerX - 90; boss.y = -183; stage.addChild (boss); Tween.get (boss) .to (y: 40, 2000) // tween de baas naar het speelgebied
De vijanden, zoals de kogels, worden ook elk frame verplaatst. Deze code vindt alle vijanden in de fase met behulp van de vijanden
container en verplaatst ze elke 5 px naar beneden.
/ * Vijanden verplaatsen * / for (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5;
We controleren ook de posities van de vijanden om ze te vernietigen wanneer ze niet langer zichtbaar zijn.
/ * Vijanden verplaatsen * / for (var j = 0; j < enemies.children.length; j++) enemies.children[j].y += 5; /* Remove Offstage Enemies */ if(enemies.children[j].y > 480 + 50) vijanden.removeChildAt (j);
De kogels in de container worden getest op aanvaring met de vijanden; wanneer dit gebeurt, worden beide verwijderd van het podium, wordt een geluid gespeeld en wordt de score bijgewerkt.
voor (var k = 0; k < bullets.children.length; k++) /* Bullet - Enemy Collision */ if(bullets.children[k].x >= vijanden.kinderen [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);
De volgende code behandelt de botsingen van de baas, het maakt gebruik van dezelfde methode die wordt gebruikt in de bullet-vijand botsing lus. Hier gebruiken we de bossHealth
variabele om te bepalen wanneer de baas verslagen is.
/ * 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);
Hier controleren we of een vijand botst met het schip van de speler; als dat zo is, wordt er een geluid afgespeeld, wordt een leven verwijderd en wordt het schip geanimeerd.
/ * Ship - Enemy Collision * / if (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 (schip) .to (y: 425, 500) SoundJS.play ('explo');
De speler wint als de baas zijn gezondheid verliest en verliest als al zijn eigen leven verloren is. De volgende regels detecteren die situaties en roepen een waarschuwingsfunctie op met behulp van de juiste parameter.
/ * Check for win * / if (baas! = Null && bossHealth <= 0) alert('win'); /* Check for lose */ if(lives.children.length <= 0) alert('lose');
De waarschuwing toont de speler informatie over de status van het spel; het wordt getoond wanneer een spelgebeurtenis wordt bereikt. Het verwijdert de game listeners en toont de juiste boodschap.
function alert (e) / * Luisteraars verwijderen * / stage.onMouseMove = null; bg.onPress = null; bg2.onPress = null; Ticker.removeListener (TKR); tkr = null; timerSource = null; / * Correct bericht weergeven * / if (e == 'win') win = nieuwe bitmap (winImg); win.x = centerX - 64; win.y = centerY - 23; stage.addChild (win); stage.removeChild (vijanden, baas); else lose = new Bitmap (loseImg); lose.x = centerX - 64; lose.y = centerY - 23; stage.addChild (verliezen); stage.removeChild (vijanden, schip); bg.onPress = function () window.location.reload ();; bg2.onPress = function () window.location.reload ();; stage.update ();
Sla uw werk op (als u dat nog niet hebt gedaan) en open het HTML-bestand in de browser om uw HTML5-game te laten werken!
Je hebt geleerd hoe je een Space Shooter-game kunt maken met alle basisfuncties, probeer het uit te breiden met wat je al weet. Een goed begin zou zijn om de vijanden of baas terug te laten schieten naar de speler.
Ik hoop dat je deze tutorial leuk vond, bedankt voor het lezen!