Lär dig CreateJS genom att bygga ett HTML5 Pong-spel

Nätet rör sig snabbt - så fort att vår ursprungliga EaselJS handledning redan är föråldrad! I den här handledningen lär du dig hur du använder den nyaste CreateJS-sviten genom att skapa en enkel Pong-klon.


Slutresultatförhandsvisning

Låt oss ta en titt på det slutliga resultatet vi ska arbeta för:

Klicka för att spela

Denna handledning bygger på Carlos Yanez Skapa ett Pong-spel i HTML5 med EaselJS, som i sin tur byggdes på hans Komma igång med EaselJS guide. Grafiken och ljudeffekterna är alla tagna från den tidigare handledningen.


Steg 1: Skapa index.html

Detta kommer att vara vår viktigaste index.html fil:

    Pong             

Som du kan se är det ganska kort och består huvudsakligen av att ladda upp CreateJS-biblioteken.

Sedan utgåvan av CreateJS (som i grunden sammanbinder alla separata EaselJS-bibliotek) behöver vi inte längre ladda ner JS-filerna och värd dem på vår hemsida. Filerna är nu placerade i ett CDN (Content Delivery Network) som gör det möjligt för oss att ladda dessa filer på distans så fort som möjligt.

Låt oss granska koden:

 

Den här raden tar bort mobilhöjdpunkten som kan visas när du försöker spela spelet på mobilen. (Den mobila höjdpunkten gör att dukobjektet blir markerat och sålunda ignorerar dina fingerrörelser.)

Därefter har vi laddningen av CreateJS-biblioteken:>

     

Denna kod laddar upp JS-filerna från CreateJS CDN och det tillåter oss i princip att använda någon av CreateJS-funktionerna i vår kod

Därefter laddas vi in ​​plug-inen SoundJS Flash, som ger ljudstöd för webbläsare som inte stöder HTML5 Audio. Detta görs genom att använda ett SWF (ett Flash-objekt) för att ladda ljuden.

 

I det här fallet använder vi inte CDN; istället laddar vi ner SoundJS-biblioteket från http://createjs.com/#!/SoundJS/download och placera soundjs.flashplugin-0.2.0.min.js och FlashAudioPlugin.swf filer i en lokal mapp som heter tillgångar.

Sist bland JS-filerna laddar vi Main.js fil som innehåller alla koden till vårt spel:

 

Till sist, låt oss placera ett Canvas-objekt på vårt stadium.

   

Nu kan vi börja arbeta med spelkoden.


Steg 2: Variablerna

Vår spelkod kommer inne i en fil med namnet Main.js, så skapa och spara det nu.

Låt oss först och främst definiera variabler för alla grafiska objekt i spelet:

 var kanvas; // Kommer att kopplas till duken i vårt index.html sida var stadium; // motsvarar scenen i AS3; vi lägger till "barn" till det // Grafik // [Bakgrund] var bg; // Bakgrundsbilden // [Titelvisning] var huvud; // Huvudbakgrunden var startB; // Startknappen i huvudmenyn var creditsB; // Krediter knappen i huvudmenyn // [Krediter] var krediter; // Credits-skärmen // [Game View] var player; // Spelaren paddle grafisk var boll; // Bollen grafisk var cpu; // CPU paddle var win; // Den vinnande popupen förlorade; // Den förlorande popupen

Jag har lagt till en kommentar för varje variabel så att du vet vad vi ska ladda i den variabeln

Nästa upp, poängen:

 // [Betyg] var playerScore; // Huvudspelarens poäng var cpuScore; // CPU-värdet var cpuSpeed ​​= 6; // CPU-spjällets hastighet; Ju snabbare det är, desto svårare är spelet

Vi behöver, variabler för bollens hastighet:

 // Variabler var xSpeed ​​= 5; var ySpeed ​​= 5;

Du kan ändra dessa värden till vad du vill, om du vill göra spelet lättare eller hårdare.

Om du är en Flash-utvecklare, vet du att Flash är onEnterFrame är mycket användbar när du skapar spel, eftersom det finns saker som måste hända i varje given ram. (Om du inte är bekant med den här idén, kolla in den här artikeln på Game Loop.)

Vi har en motsvarighet för onEnterFrame i CreateJS, och det är ticker objekt, som kan köra kod varje bråkdel av en sekund. Låt oss skapa den variabel som länkar till den:

 var tkr = nytt objekt;

Därefter har vi förprogrammeraren, som kommer att använda de nya PreloadJS-metoderna.

 // preloader var preloader; var manifest; var totalLadad = 0;
  • preloader - kommer att innehålla PreloadJS-objektet.
  • manifestera - kommer att hålla listan över filer vi behöver ladda.
  • totalLoaded - Denna variabel innehåller antalet filer som redan laddats.

Sist men inte minst i vår lista över variabler har vi TitleView, som kommer att innehålla flera grafik in för att visa dem tillsammans (som en Flash Display).

 var TitleView = ny behållare ();

Låt oss gå vidare till huvudfunktionen ...


Steg 3: Huvudfunktionen ()

Den här funktionen är den första funktionen som körs efter alla JS-filer från index.html laddas. Men vad ringer den här funktionen?

Tja, kom ihåg den här raden från index.html fil?

 

I kodfältet anges att när HTML- och JS-biblioteken är laddade, Huvudsaklig funktionen bör köras.

Låt oss granska det:

 funktion Main () / * Link Canvas * / canvas = document.getElementById ('PongStage'); scen = nytt scen (kanfas); stage.mouseEventsEnabled = true; / * Ange Flash Plugin för webbläsare som inte stöder SoundJS * / SoundJS.FlashPlugin.BASE_PATH = "assets /"; om (! SoundJS.checkPlugin (true)) alert ("Error!"); lämna tillbaka;  manifest = [src: "bg.png", id: "bg", src: "main.png", id: "main", src: "startB.png", id: "startB" , src: "creditsB.png", id: "creditsB", src: "credits.png", id: "credits", src: "paddle.png", id: "cpu", src: "paddle.png", id: "player", src: "ball.png", id: "boll", src: "win.png", id: "win", src : "lose.png", id: "lose", src: "playerScore.mp3 | playerScore.ogg", id: "playerScore", src: "enemyScore.mp3 | enemyScore.ogg", id: " fiendeScore ", src:" hit.mp3 | hit.ogg ", id:" hit ", src:" wall.mp3 | wall.ogg ", id:" wall "]; preloader = ny PreloadJS (); preloader.installPlugin (SoundJS); preloader.onProgress = handleProgress; preloader.onComplete = handleComplete; preloader.onFileLoad = handleFileLoad; preloader.loadManifest (manifest); / * Ticker * / Ticker.setFPS (30); Ticker.addListener (steg); 

Låt oss bryta ner varje del:

 kanfas = document.getElementById ('PongStage'); scen = nytt scen (kanfas); stage.mouseEventsEnabled = true;

Här länkar vi till PongStage Canvas objekt från index.html fil till kanfasvariabeln och skapa sedan ett scenobjekt från den duken. (Scenen låter oss placera objekt på den.)

mouseEventsEnabled gör det möjligt för oss att använda mushändelser, så vi kan upptäcka musrörelser och klick.

 / * Ange Flash Plugin för webbläsare som inte stöder SoundJS * / SoundJS.FlashPlugin.BASE_PATH = "assets /"; om (! SoundJS.checkPlugin (true)) alert ("Error!"); lämna tillbaka; 

Här konfigurerar vi var Flash-ljud plugin finns för de webbläsare där HTML5 Audio inte stöds

 manifest = [src: "bg.png", id: "bg", src: "main.png", id: "main", src: "startB.png", id: "startB" , src: "creditsB.png", id: "creditsB", src: "credits.png", id: "credits", src: "paddle.png", id: "cpu",  src: "paddle.png", id: "player", src: "ball.png", id: "boll", src: "win.png", id: "win", src: "lost.png", id: "lose", src: "playerScore.mp3 | playerScore.ogg", id: "playerScore", src: "enemyScore.mp3 | enemyScore.ogg", id: "enemyScore ", src:" hit.mp3 | hit.ogg ", id:" hit ", src:" wall.mp3 | wall.ogg ", id:" wall "];

I manifestvariabeln placerar vi en rad filer vi vill ladda (och ge ett unikt ID för var och en). Varje ljud har två format - MP3 och OGG - eftersom olika webbläsare är kompatibla med olika format.

 preloader = ny PreloadJS (); preloader.installPlugin (SoundJS); preloader.onProgress = handleProgress; preloader.onComplete = handleComplete; preloader.onFileLoad = handleFileLoad; preloader.loadManifest (manifest);

Här konfigurerar vi preloader objektet med PreloadJS. PreloadJS är ett nytt tillägg till CreateJS-biblioteken och ganska användbar.

Vi skapar ett nytt PreloadJS-objekt och placerar det i preloader variabel, tilldela sedan en metod till varje händelse (på framsteg, onComplete, onFileLoad). Slutligen använder vi preloader att ladda manifestet vi skapade tidigare.

 Ticker.setFPS (30); Ticker.addListener (steg);

Här lägger vi Ticker-objektet till scenen och ställer in bildfrekvensen till 30 FPS. vi använder det senare i spelet för enterframe funktionalitet.


Steg 4: Skapa preloaderfunktionerna

 funktionshanteringProgress (händelse) // använd händelse.laddad för att få procentandelen av laddningsfunktionen handlaFullständig (händelse) // utlöses när alla laddningar är färdiga funktionhandbokFileLoad (händelse) // utlöses när en enskild fil fyller i switch (event.type) case PreloadJS.IMAGE: // image loaded var img = ny bild (); img.src = event.src; img.onload = handleLoadComplete; fönster [event.id] = ny bitmapp (img); ha sönder; fallet PreloadJS.SOUND: // ljudbelastat handtagLådaComplete (); ha sönder; 

Låt oss granska funktionerna:

  • handleProgress - I den här funktionen kan du följa procentandelen av laddningsförloppet med den här parametern: event.loaded. Du kan använda detta för att till exempel skapa en statusfält.
  • handleComplete - Den här funktionen kallas när alla filer har laddats (om du vill placera något där).
  • handleFileLoad - Eftersom vi laddar två typer av filer - bilder och ljud - vi har denna funktion som hanterar var och en separat. Om det är en bild skapar vi en bitmapps bild och placerar den i en variabel (vars namn är detsamma som ID för den laddade bilden) och sedan ringer den handleLoadComplete funktion (som vi skriver nästa); om det är ett ljud så kallar vi bara handleLoadComplete omedelbart.

Låt oss nu diskutera handleLoadComplete funktion som jag just nämnde:

 funktionshandtagLadda Komplettera (händelse) totalLoaded ++; om (manifest.length == totalLoaded) addTitleView (); 

Det är en ganska enkel funktion; vi ökar totalLoaded variabel (som innehåller det antal tillgångar som laddats hittills) och sedan kontrollerar vi om antalet objekt i vårt manifest är detsamma som antalet laddade tillgångar, och i så fall går du till huvudmenyskärmen.


Steg 5: Skapa huvudmenyn

 funktion addTitleView () //console.log("Add Title View "); startB.x = 240 - 31,5; startB.y = 160; startB.name = 'startB'; poängB.x = 241 - 42; creditsB.y = 200; TitleView.addChild (huvud, startB, krediterB); stage.addChild (bg, TitleView); stage.update (); // Knapp Lyssnare startB.onPress = tweenTitleView; creditsB.onPress = showCredits;

Inget speciellt här. Vi placerar bilderna på knappen Bakgrund, Startknapp och Krediter på scenen och länken onPress händelsehanterare till start- och kreditknapparna.

Här är de funktioner som visar och tar bort krediteringsskärmen och tweenTitleView som startar spelet:

 funktion showCredits () // Visa Credits credits.x = 480; stage.addChild (hp); stage.update (); Tween.get (credits) .to (x: 0, 300); credits.onPress = hideCredits;  // Hide Credits funktion hideCredits (e) Tween.get (credits) .to (x: 480, 300) .call (rmvCredits);  // Ta bort Credits funktion rmvCredits () stage.removeChild (credits);  // Tween Title View funktionen tweenTitleView () // Starta Game Tween.get (TitleView) .to (y: -320, 300) .call (addGameView); 

Steg 6: Spelkoden

Vi har nått huvuddelen av denna handledning som är koden för spelet själv.

Först av allt måste vi lägga till alla nödvändiga tillgångar på scenen, så gör vi det i addGameView fungera:

 funktion addGameView () // Destroy Menu & Credits skärm stage.removeChild (TitleView); TitleView = null; krediter = null; // Lägg till spelvisning player.x = 2; player.y = 160 - 37.5; cpu.x = 480 - 25; cpu.y = 160-37,5; boll.x = 240-15; boll.y = 160-15; // Score playerScore = new Text ('0', 'bold 20px Arial', '# A3FF24'); playerScore.x = 211; playerScore.y = 20; cpuScore = ny text ('0', 'fet 20px Arial', '# A3FF24'); cpuScore.x = 262; cpuScore.y = 20; stage.addChild (playerScore, cpuScore, spelare, cpu, boll); stage.update (); // Start Listener bg.onPress = startGame; 

Återigen, en ganska enkel funktion som placerar objekten på skärmen och lägger till en mouseEvent på bakgrundsbilden, så att när användaren klickar på det startar spelet (vi ringer upp starta spelet fungera).

Låt oss granska starta spelet fungera:

 funktion startspel (e) bg.onPress = null; stage.onMouseMove = movePaddle; Ticker.addListener (tkr, false); tkr.tick = update; 

Här, som du kan se, förutom att lägga till en onMouseMove händelse som kommer att flytta vår paddla. Vi lägger till bock händelse som kommer att ringa till uppdatering funktion i varje ram.

Låt oss granska movePaddle och återställa funktioner:

 funktion movePaddle (e) // Mouse Movement player.y = e.stageY;  / * Återställ * / Funktionsåterställning () ball.x = 240-15; boll.y = 160-15; player.y = 160 - 37.5; cpu.y = 160-37,5; stage.onMouseMove = null; Ticker.removeListener (tkr); bg.onPress = startGame; 

I movePaddle, vi placerar i grunden användarens paddel på musens y-koordinat.

I återställa, vi gör något liknande addGameView, utom här lägger vi inte till några grafiska element eftersom de redan finns på skärmen.

Använda varna funktion vi visar den vinnande och förlorande popupen:

 funktionsvarning (e) Ticker.removeListener (tkr); stage.onMouseMove = null; bg.onPress = null om (e == 'win') win.x = 140; win.y = -90; stage.addChild (win); Tween.get (win) .to (y: 115, 300);  annat lose.x = 140; lose.y = -90; stage.addChild (förlorar); Tween.get (förlora) .to (y: 115, 300); 

Steg 7: Game Loop

Nu, för den sista delen av vår handledning arbetar vi på uppdatering funktion (som förekommer i varje ram i spelet - som liknar Flash onEnterFrame):

 funktionsuppdatering () // Ball Movement ball.x = ball.x + xSpeed; ball.y = ball.y + ySpeed; // Cpu Movement om (cpu.y < ball.y)  cpu.y = cpu.y + 4;  else if(cpu.y > ball.y) cpu.y = cpu.y - 4;  // Wall Collision om ((ball.y) < 0)  ySpeed = -ySpeed; SoundJS.play('wall'); ;//Up if((ball.y + (30)) > 320) ySpeed ​​= -ySpeed; SoundJS.play ('wall');; // ner / * CPU-poäng * / om ((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); återställa(); SoundJS.play ( 'playerScore');  / * Cpu kollision * / om (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');  /* Stop Paddle from going out of canvas */ if(player.y >= 249) player.y = 249;  / * Kontrollera om Win * / if (playerScore.text == '10') alert ('win');  / * Kontrollera om spelet över * / if (cpuScore.text == '10') alert ('lose'); 

Ser skrämmande, eller hur? Oroa dig inte, vi granskar varje del och diskuterar den.

 // Ball Movement ball.x = ball.x + xSpeed; ball.y = ball.y + ySpeed;

I varje ram kommer bollen att röra sig enligt dess x- och y-hastighetsvärden

 // Cpu-rörelse om ((cpu.y + 32) < (ball.y-14))  cpu.y = cpu.y + cpuSpeed;  else if((cpu.y+32) > (ball.y + 14)) cpu.y = cpu.y - cpuSpeed; 

Här har vi datorns grundläggande AI, där datorns paddel bara följer bollen utan någon speciell logik. Vi jämför bara placeringen av paddelens mittpunkt (det är därför vi lägger till 32 pixlar till cpu Y-värdet) till bollens läge, med en liten förskjutning och flytta paddeln upp eller ner efter behov.

 if ((ball.y) < 0)  //top ySpeed = -ySpeed; SoundJS.play('wall'); ; if((ball.y + (30)) > 320) // botten ySpeed ​​= -ySpeed; SoundJS.play ( 'vägg'); ;

Om bollen träffar den övre gränsen eller den nedre gränsen på skärmen ändras bollen riktning och vi spelar Wall Hit-ljudet.

 / * CPU-poäng * / om ((boll.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); återställa(); SoundJS.play ( 'playerScore'); 

Poänginloggningen är enkel: om bollen passerar till vänster eller höger gränser ökar poängen för spelaren respektive processorn, spelar ett ljud och återställer objektens plats med hjälp av återställa funktion som vi har diskuterat tidigare.

 / * CPU kollision * / om (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'); 

Här handlar vi om kollisioner av bollen med paddlarna; varje gång bollen träffar en av paddlarna ändras bollen riktning och ett ljud spelas

 om (player.y> = 249) player.y = 249; 

Om spelarens paddel går ut ur gränsen lägger vi tillbaka den inom gränserna.

 / * Kontrollera för Win * / if (playerScore.text == '10') alert ('win');  / * Kontrollera om spelet över * / if (cpuScore.text == '10') alert ('lose'); 

I det här bandet kontrollerar vi om någon av spelarnas poäng har nått 10 poäng och i så fall visar vi den vinnande eller förlorande popupen till spelaren (enligt hans vinnande status).


Slutsats

Det är det, du har skapat ett helt pongspel med CreateJS. Tack för att du tog dig tid att läsa den här handledningen.