Maak een eenvoudige Space Shooter Game in HTML5 met EaselJS

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.


Eindresultaat voorbeeld

Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:


Klik om de demo af te spelen.


Stap 1: Kort overzicht

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.


Stap 2: Interface

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.


Stap 3: download EaselJS

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.


Stap 4: HTML-structuur

Laten we ons HTML-document voorbereiden, het is een eenvoudige HTML-structuur om onze app te schrijven. Bewaar deze als Shooter.html.

    schutter    

Stap 5: Verberg Mobile Hightlight

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     

Stap 6: JavaScript-bibliotheken

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.


Stap 7: Hoofdfunctie oproepen

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         

Stap 8: Canvaselement

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          

Stap 9: JavaScript starten

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.


Stap 10: Definieer Canvas

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;

Stap 11: Achtergrond

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;

Stap 12: Schip

Dit is het schip dat zal worden gebruikt als het personage of de held van de speler.

 / * Verzenden * / var sImg = new Image (); var schip;

Stap 13: Vijand

Meerdere vijanden zullen op het podium staan; ze gebruiken dit als de bronafbeelding.

 / * Enemy * / var eImg = new Image ();

Stap 14: Baas

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;

Stap 15: levens

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 ();

Stap 16: Opsommingstekens

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 ();

Stap 17: waarschuw grafische afbeeldingen

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;

Stap 16: Variabelen

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

Stap 17: Geluiden

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.


Stap 18: Hoofdfunctie

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 ...

Stap 19: Link Canvas

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);

Stap 20: Schakel muisgebeurtenissen in

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;

Stap 21: Laad geluiden

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]);

Stap 22: grafische afbeeldingen laden

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;

Stap 23: Stel Ticker in

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);

Stap 24: Preload-functie

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 (); 

Stap 25: Spelweergave toevoegen

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); 

Stap 26: Verplaats het schip

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.


Stap 27: Schiet

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'); 

Stap 28: Vijandfunctie toevoegen

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 (); 

Stap 29: Start Game

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); 

Stap 30: Verplaats achtergrond

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; 

Stap 31: Verplaats kogels

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; 

Stap 32: Offstage Bullets verwijderen

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);  

Stap 33: Toon baas

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

Stap 34: Verplaats vijanden

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;

Stap 35: verwijder off-stage vijanden

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); 

Stap 36: Bullet - Enemy Collision

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); 

Stap 37: Bullet - Boss Collision

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);  

Stap 38: Schip - vijandelijke botsing

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'); 

Stap 39: Check for Win of Lose

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');  

Stap 40: Waarschuwing

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 (); 

Stap 41: Test



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!


Conclusie

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!