In deze zelfstudie maken we een kloon van het klassieke spel, Pong, in HTML5, met behulp van de Easel JS-bibliotheek. De game heeft meerdere schermen, geluidseffecten en een (zeer eenvoudige) AI-tegenstander.
Met behulp van vooraf gemaakte afbeeldingen coderen we een leuke pong spel in HTML5 met de Easel JS-bibliotheek, die een Flash-achtige interface voor het HTML5-canvas biedt. Zie dit Activetuts + -artikel voor een inleiding tot EaselJS.
De speler kan een paddle besturen met de muis en tegen de tegenstander van de computer-controller spelen om punten te krijgen.
Een eenvoudige interface met een neo-futuristische stijl zal worden gebruikt; dit omvat meerdere vormen, knoppen, bitmaps en meer.
De grafische voorstellingen 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.
U kunt de nieuwste versie van EaselJS downloaden van de officiële website. Dit kan hier echter incompatibel zijn met de code, dus ik raad aan om de versie van de bibliotheek te gebruiken die bij de brondownload is inbegrepen.
Laten we ons HTML-document voorbereiden. We beginnen met de basisprincipes, alleen een overzicht van barebones:
pong
We moeten ook een klein beetje CSS toevoegen om de standaardmarkering te verwijderen die wordt toegepast wanneer u op een element in een mobiele browser tikt. Zonder dit zou de mobiele ervaring drastisch afnemen.
pong
De volgende code voegt de nodige javascript-bibliotheken toe om onze app te laten werken.
pong /
Naast EaselJS gebruiken we ook TweenJS (voor het omgaan met schermovergangen en de gamelus) en SoundJS (voor de geluidseffecten).
main.js
is het bestand dat we zullen gebruiken om onze eigen JS-code te houden.
In de volgende regels noemen we onze Hoofd()
functie. Dit is de functie waarmee onze applicatie wordt gestart; het wordt later in de zelfstudie, binnen gemaakt main.js
.
pong
Een HTML5-canvas wordt op deze regel gemaakt; we kennen het een ID toe zodat we er later naar kunnen verwijzen en ook de breedte en hoogte ervan kunnen instellen.
pong
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 de code. Vergeet niet om het bestand op te slaan als main.js
in je projectmap.
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 AS3-fase.
/ * Definieer Canvas * / var canvas; var stadium;
Deze variabele slaat de titelachtergrond op.
/ * Achtergrond * / var bgImg = new Image (); var bg;
Dit is de titelweergave, het eerste interactieve scherm dat in onze game verschijnt. Deze variabelen slaan de componenten op.
/ * Titelweergave * / var mainImg = new Image (); var main; var startBImg = new Image (); var startB; var creditsBImg = new Image (); var creditsB; var TitleView = nieuwe container ();
In deze weergave worden de aftiteling, het jaar en het auteursrecht van het spel weergegeven. Deze variabelen worden gebruikt om het spel op te slaan.
/ * Credits * / var creditsViewImg = new Image (); var credits;
In de volgende variabelen worden de afzonderlijke afbeeldingen opgeslagen die in de gameweergave worden weergegeven:
/ * Spelweergave * / var playerImg = nieuw afbeelding (); var speler; var ballImg = new Image (); var bal; var cpuImg = new Image (); var cpu; var winImg = new Image (); var win; var loseImg = new Image (); var verliezen;
De scorewaarden worden afgehandeld door de volgende variabelen:
/ * Score * / var playerScore; var cpuScore;
Dit zijn de variabelen die we zullen gebruiken, lees de opmerkingen in de code om te begrijpen waarvoor ze zijn:
var xSpeed = 5; // Horizontale snelheid van de bal var ySpeed = 5; // Verticale snelheid van de bal var gfxLoaded = 0; // gebruikt als een preloader, telt de reeds geladen items var tkr = new Object; // gebruikt als gebeurtenislistener voor de Ticker
We zullen geluidseffecten gebruiken om het gevoel van het spel te verbeteren. De geluiden in dit voorbeeld zijn gemaakt met de uitstekende gratis tool as3sfxr en geconverteerd naar MP3 met Audacity.
De benodigde geluiden zijn allemaal te vinden in de brondownload. Als je je eigen wilt maken, heb je er vier nodig:
hit.mp3
: gespeeld wanneer de bal een peddel raaktplayerScore.mp3
: gespeeld wanneer ze speler scoortenemyScore.mp3
: gespeeld wanneer de vijand scoortwall.mp3
: gespeeld wanneer de bal de boven- of ondergrens raaktDe 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 zal de nodige functies oproepen om het spel te starten.
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. Voeg dit toe aan Hoofd()
.
/ * Link Canvas * / canvas = document.getElementById ('Pong'); 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. Voeg dit toe aan Hoofd()
.
stage.mouseEventsEnabled = true;
We gebruiken SoundJS om geluiden aan onze game toe te voegen; schrijf de volgende code om de geluiden te importeren die we zullen gebruiken. Voeg dit toe aan Hoofd()
.
/ * Geluid * / SoundJS.addBatch ([name: 'hit', src: 'hit.mp3', instanties: 1, naam: 'playerScore', src: 'playerScore.mp3', instanties: 1, name: 'enemyScore', src: 'enemyScore.mp3', instanties: 1, name: 'wall', src: 'wall.mp3', exemplaren: 1]);
Deze code wordt gebruikt om de afbeeldingen vooraf te laden met behulp van een functie die we later zullen schrijven. Hiermee worden de afbeeldingsobjecten ingesteld die we eerder hebben gemaakt om te verwijzen naar de relevante bron-PNG-bestanden in onze documentenmap.
Aan elk wordt een naam gegeven, zodat we kunnen detecteren welk beeld later wordt geladen en tot slot de functie die de geladen afbeeldingen afhandelt.
Voeg dit toe aan Hoofd()
.
/ * Laad GFX * / bgImg.src = 'bg.png'; bgImg.name = 'bg'; bgImg.onload = loadGfx; mainImg.src = 'main.png'; mainImg.name = 'main'; mainImg.onload = loadGfx; startBImg.src = 'startB.png'; startBImg.name = 'startB'; startBImg.onload = loadGfx; creditsBImg.src = 'creditsB.png'; creditsBImg.name = 'creditsB'; creditsBImg.onload = loadGfx; creditsViewImg.src = 'credits.png'; creditsViewImg.name = 'credits'; creditsViewImg.onload = loadGfx; playerImg.src = 'paddle.png'; playerImg.name = 'speler'; playerImg.onload = loadGfx; ballImg.src = 'ball.png'; ballImg.name = 'bal'; ballImg.onload = loadGfx; cpuImg.src = 'paddle.png'; cpuImg.name = 'cpu'; cpuImg.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 gecentraliseerde vink of heartbeat die met een ingesteld interval wordt uitgezonden. Dit kan worden gebruikt om de gamelus te activeren.
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. Voeg dit toe aan Hoofd()
.
/ * Ticker * / Ticker.setFPS (30); Ticker.addListener (trap);
Elke keer dat een afbeelding wordt geladen, wordt deze functie uitgevoerd. Het wijst elke afbeelding toe aan een bitmapobject en controleert of alle elementen zijn geladen voordat verder wordt gegaan.
functie loadGfx (e) if (e.target.name = 'bg') bg = nieuwe Bitmap (bgImg); if (e.target.name = 'main') main = new Bitmap (mainImg); if (e.target.name = 'startB') startB = new Bitmap (startBImg); if (e.target.name = 'creditsB') creditsB = new Bitmap (creditsBImg); if (e.target. name = 'credits') credits = nieuwe Bitmap (creditsViewImg); if (e.target.name = 'player') player = nieuwe Bitmap (playerImg); if (e.target.name = 'ball') ball = new Bitmap (ballImg); if (e.target.name = 'cpu') cpu = new Bitmap (cpuImg); if (e.target.name = 'win') win = new Bitmap ( winImg); if (e.target.name = 'lose') lose = new Bitmap (loseImg); gfxLoaded ++; if (gfxLoaded == 10) // vergeet dit niet te veranderen als u meer afbeeldingen toevoegt addTitleView ();
Wanneer alle afbeeldingen zijn geladen, wordt de titelweergave aan het werkgebied toegevoegd met de volgende functie:
function addTitleView () startB.x = 240 - 31.5; startB.y = 160; startB.name = 'startB'; creditsB.x = 241 - 42; creditsB.y = 200; TitleView.addChild (main, startB, creditsB); stage.addChild (bg, TitleView); stage.update ();
Deze functie voegt de nodige luisteraars toe aan de TitleView knoppen (het maakt deel uit van addTitleView ()
):
startB.onPress = addGameView; creditsB.onPress = showCredits;
De credits scherm wordt getoond wanneer de gebruiker op de knop credits klikt; een muisluisteraar wordt toegevoegd aan de volledige afbeelding om deze te verwijderen.
function showCredits () // Toon credits credits.x = 480; stage.addChild (credits); stage.update (); Tween.get (credits) .to (x: 0, 300); credits.onPress = hideCredits;
Wanneer de credits op het scherm wordt geklikt, het wordt terug getweend en van het werkgebied verwijderd.
// Hide Credits function hideCredits (e) Tween.get (credits) .to (x: 480, 300) .call (rmvCredits); // Functie Credits verwijderen rmvCredits () stage.removeChild (credits);
Laten we hier stoppen om te testen wat we tot nu toe hebben gedaan. Klik hier voor een mijlpaaldemo.
Houd er rekening mee dat sommige regels zijn weggelaten omdat sommige functies nog niet zijn gemaakt.
Vergeet niet dat de mijlpaal is opgenomen in de bronbestanden, dus als om wat voor reden dan ook uw bestand deze niet nabootst, vergelijk dan uw bron met de mijne om te zien wat de oorzaak zou kunnen zijn.
De volgende regels verwijderen de TitleView van het podium en voegt de GameView items naar het podium. Een muisluisteraar wordt toegevoegd aan de achtergrond om het spel te starten wanneer erop wordt geklikt.
functie addGameView () // Vernietig Menu & Credits scherm stage.removeChild (TitleView); TitleView = null; credits = null; // Voeg Game View player.x = 2 toe; player.y = 160 - 37.5; cpu.x = 480 - 25; cpu.y = 160 - 37.5; ball.x = 240 - 15; ball.y = 160 - 15; // Score playerScore = nieuwe tekst ('0', 'bold 20px Arial', '# A3FF24'); playerScore.maxWidth = 1000; // fix voor Chrome 17 playerScore.x = 211; playerScore.y = 20; cpuScore = nieuwe tekst ('0', 'bold 20px Arial', '# A3FF24'); cpuScore.maxWidth = 1000; // fix voor Chrome 17 cpuScore.x = 262; cpuScore.y = 20; stage.addChild (playerScore, cpuScore, player, cpu, ball); stage.update (); // Start Listener bg.onPress = startGame;
De speler beweegt mee met de verticale positie van de muis:
functie movePaddle (e) // Muisbeweging player.y = e.stageY;
Deze code wordt uitgevoerd wanneer de speler op de achtergrond van het spel klikt, het voegt de muislistener toe die de functie in de vorige stap activeert, en voegt een lichtkrant toe om de spellus te besturen.
Besteed aandacht aan de manier waarop de ticker is gemaakt: het is het equivalent van een timergebeurtenis in AS3.
function startGame (e) bg.onPress = null; stage.onMouseMove = movePaddle; Ticker.addListener (tkr, false); tkr.tick = update;
Wanneer een punt wordt gescoord (door de speler of de computer), keren de paddles en de bal terug naar hun oorspronkelijke posities en wordt het spel onderbroken:
functie reset () ball.x = 240 - 15; ball.y = 160 - 15; player.y = 160 - 37.5; cpu.y = 160 - 37.5; stage.onMouseMove = null; // stop met luisteren naar de muis Ticker.removeListener (tkr); // pauzeer het spel bg.onPress = startspel;
Als het spel niet is gepauzeerd, wordt de bal elk frame verplaatst met behulp van de variabelen die we eerder hebben gemaakt.
functie-update () // Balverplaatsing ball.x = ball.x + xSpeed; ball.y = ball.y + ySpeed;
Deze code regelt de beweging van de computer; de peddel wordt zodanig bewogen dat deze de bal volgt terwijl er nog steeds een foutmarge is.
if (cpu.y < ball.y) cpu.y = cpu.y + 2.5; else if(cpu.y > ball.y) cpu.y = cpu.y - 2.5;
Hier controleren we of de bal zich aan de boven- of onderrand van het canvas bevindt; in dat geval wordt de verticale snelheid omgekeerd en klinkt er een geluid.
if ((bal.y) < 0) ySpeed = -ySpeed; SoundJS.play('wall');;//Up if((ball.y + (30)) > 320) ySpeed = -ySpeed; SoundJS.play ( 'wand'); // beneden
Nu de linker- en rechterkant. Deze code wijzigt ook de score, roept de reset-functie aan en speelt een ander geluid afhankelijk van de kant die de bal heeft aangeraakt.
/ * CPU-score * / if ((ball.x) < 0) xSpeed = -xSpeed; cpuScore.text = parseInt(cpuScore.text + 1); reset(); SoundJS.play('enemyScore'); /* Player Score */ if((ball.x + (30)) > 480) xSpeed = -xSpeed; playerScore.text = parseInt (playerScore.text + 1); reset (); SoundJS.play (playerScore);
De volgende code controleert of de bal botst met een paddle, door de positie van de paddle te vergelijken met de coördinaten van de bal. Als de selectiekaders van de twee elkaar kruisen, is er een botsing, dus we keren de x-snelheid van de bal om en spelen een geluid.
/ * Cpu-botsing * / if (ball.x + 30> cpu.x && ball.x + 30 < cpu.x + 22 && ball.y >= cpu.y && ball.y < cpu.y + 75) xSpeed *= -1; SoundJS.play('hit'); /* Player collision */ if(ball.x <= player.x + 22 && ball.x > player.x && ball.y> = player.y && ball.y < player.y + 75) xSpeed *= -1; SoundJS.play('hit');
U kunt de eindvoorwaarde in de volgende regels wijzigen - deze is standaard ingesteld op 10 punten.
/ * Check for Win * / if (playerScore.text == '10') alert ('win'); / * Controleer of Game Over * / if (cpuScore.text == '10') alert ('lose');
Deze functie zal het spel stoppen en een waarschuwing weergeven, waarvan de inhoud afhangt van het spelresultaat.
functie alert (e) Ticker.removeListener (tkr); stage.onMouseMove = null; bg.onPress = null if (e == 'win') win.x = 140; win.y = -90; stage.addChild (win); Tween.get (win) .to (y: 115, 300); else lose.x = 140; lose.y = -90; stage.addChild (verliezen); Tween.get (verliest) .to (y: 115, 300);
Sla je werk op (als je dat nog niet hebt gedaan) en open het HTML-bestand in de browser om te zien hoe je game werkt!
Probeer de variabelen van de game aan te passen om uw eigen versie van de game te maken!
Ik hoop dat je deze tutorial leuk vond, bedankt voor het lezen!