Ai vrut vreodată să faci un platformer, dar nu prea dornic să scrii întregul cod de la zero? Citrus Engine nu elimină în întregime codul, dar îl face mult mai simplu, cu multe funcții utile de joc 2D construite chiar înăuntru. În acest tutorial îl vom folosi pentru a construi un joc simplu de platformă.
În acest tutorial vom folosi un popular motor Flash Game, numit Citrus, și o serie de clase ActionScript pentru a crea un joc platformer.
Deschideți Flash și creați un document de 420x280px. Setați rata cadrelor la 30fps.
Vom folosi aceste grafice de pixeli extraordinare de către Guillaume Moreau. Le puteți descărca de la opengameart.org.
Pentru fundal, schimbați culoarea scenei în # 99D9EA sau utilizați instrumentul Rectangle (R) pentru a desena un dreptunghi de acea culoare.
Va apărea o alertă atunci când jucătorul va completa nivelul sau va muri; acesta va afișa un joc peste mesaj și scorul. Folosește Instrumentul dreptunghiului pentru ao crea și a seta numele de instanță la AlertView. Marcați Exportați pentru ActionScript și dați-i același nume de clasă.
Există multe alte obiecte în joc (de exemplu: un ecran de titlu, diferitele simboluri pentru fiecare sprite, terenul). Mai degrabă decât să explici cum să le creați aici, vă sugerez să descărcați fișierele sursă și să priviți ce obiecte sunt în biblioteca FLA. Puteți folosi aceleași simboluri în propriul joc sau puteți crea altele noi!
Vom folosi un font bitmap în joc; deoarece vom folosi fontul în mod dinamic, va trebui să îl încorporăm în aplicație. Folosesc fonturile 04b11 și Arcade Classic.
Selectați un câmp de text dinamic cu fontul preferințelor dvs. și faceți clic pe Încorporare… buton în Panoul Proprietăți.
Selectați / adăugați toate caracterele necesare și faceți clic pe O.K.
Vom folosi efecte de sunet pentru a spori senzația jocului. Sunetele folosite în acest exemplu au fost generate folosind as3sfxr și sunt incluse în fișierele sursă.
Vom folosi un motor tween diferit de cel implicit inclus în Flash. Acest lucru va crește performanța și va fi mai ușor de utilizat.
Puteți descărca TweenNano de pe site-ul său oficial.
Vom folosi motorul Citrus pentru a ne alimenta jocul.
Ce este motorul Citrus? Aflați mai multe de pe site-ul său web:
Citrus Engine este un motor profesionist de calitate, cu scalabilitate Flash, construit pentru jocuri de calitate în industrie. Este construit pe practicile moderne de programare Flash, permițându-vă să vă concentrați asupra modului în care jocul dvs. este minunat! Acesta este încorporat cu un kit de pornire "platformer", pe care îl puteți folosi pentru a face cu ușurință jocuri minunate de joc sidescrolling 2D.
Accesați pagina de descărcare și obțineți fișierele necesare. Deschideți Preferințe Flash, selectați ActionScript din lista din stânga și faceți clic pe Setările ActionScript 3.0 ... , apoi adăugați calea către surse, așa cum se arată în imaginea de mai sus.
Vom face aplicația interactivă utilizând o clasă externă. Adăugați numele (Principal
) la Clasă domeniu în Publica secțiunea din Proprietăți pentru a asocia FLA cu clasa de documente principale.
Creați o nouă clasă ActionScript 3.0 (Cmd + N) și salvați-o ca Main.as în dosarul dvs. de clasă.
Creați structura claselor de bază pentru a începe să scrieți codul.
pachet public class Principal funcția publică Main (): void // code constructor
Main.as
Principal
clasa va pregăti motorul Citrus să se ocupe de primul nivel.
pachet import com.citrusengine.core.CitrusEngine; clasa publica finala principala extinde CitrusEngine functia publica finala Main (): void super (); state = new Nivel ();
Această clasă extinde clasa CitrusEngine și stabilește starea jocului la Nivel, care este numele clasei care va conține tot comportamentul jocului nostru.
Level.as
Clasa de stat este una din clasele de bază ale tehnologiei Citrus Engine și ar trebui să extindeți această clasă pentru a crea logica jocului pentru nivelurile sau stările dvs. În acest exemplu Nivel clasa se extinde Stat pentru a crea primul nivel al jocului.
Creați o nouă clasă ActionScript 3.0 (Cmd + N) și salvați-o ca Level.as în dosarul dvs. de clasă.
Acestea sunt clasele pe care trebuie să le importăm pentru noi Nivel
clasa de lucru. import
directiva face ca clasele și pachetele definite extern să fie disponibile pentru codul dvs..
import flash.display.MovieClip; import flash.display.Sprite; importul flash.events.MouseEvent; import com.citrusengine.core.CitrusEngine; import com.citrusengine.core.State; import com.citrusengine.physics.Box2D; import com.citrusengine.objects.platformer. *; import com.citrusengine.objects. *; import com.citrusengine.math.MathVector; importul flash.events.Event; import flash.geom.Rectangle; import flash.ui.Keyboard; import flash.events.KeyboardEvent; import flash.text.TextField; import flash.text.TextFormat; import com.greensock.TweenNano; import com.greensock.easing.Expo; import flash.net.navigateToURL; import flash.net.URLRequest; import flash.filters.GlowFilter; import flash.filters.BitmapFilter;
Acestea sunt variabilele pe care le vom folosi; citiți comentariile din cod pentru a afla mai multe despre ele. (Unele dintre numele lor sunt explicative, deci nu există nici un comentariu.)
privat nivel varVizualizare: LevelView = new LevelView (); // Sprite din Biblioteca privată var ero: Hero; private var inims: Vector.= Vector nou. (); privat var tf: TextFormat = TextFormat nou ('ArcadeClassic', 17, 0xFFFFFF, null, null, null, null, null, 'right'); private var scorTF: TextField = TextField nou (); privat var gemSnd: GemSnd = nou GemSnd (); // Snd = Sunetul privat de sunete privatSind: GoalSnd = GoalSnd () nou; private var hitSnd: HitSnd = nou HitSnd (); privat var jumpSnd: JumpSnd = nou JumpSnd (); private var loseSnd: LoseSnd = nou LoseSnd (); private var baddySnd: BaddySnd = nou BaddySnd ();
Constructorul este o funcție care rulează atunci când un obiect este creat dintr-o clasă, acest cod este primul care se execută atunci când faceți o instanță a unui obiect, se încarcă odată ce jocul pornește dacă este parte a clasei de document.
Se numește funcțiile necesare pentru a începe jocul. Verificați aceste funcții în pașii următori.
funcția publică finală Nivel (): void // Code
Vom începe prin a întrerupe jocul; acest lucru va împiedica motorul să adauge graficul în timp ce sprite Level View este pe scenă.
funcția publică finală Nivel (): void super (); // codul de instalare implicit CitrusEngine.getInstance () play = false; // pauza de fapt
Acest lucru va adăuga Level View sprite la scenă, precum și un ascultător al mouse-ului pentru al elimina.
suprascrie funcția publică initialize (): void / * Level Start View * / addChild (levelView); nivelView.addEventListener (MouseEvent.MOUSE_UP, startLevel);
Următoarea funcție se execută la apăsarea butonului Vizualizare nivel și se va ocupa de logica pentru a începe jocul.
funcția finală privată finală startLevel (e: MouseEvent): void
Acest cod distruge instanța de vizualizare a nivelului.
nivelView.removeEventListener (MouseEvent.MOUSE_UP, startLevel); removeChild (levelView); levelView = null;
Acum, desfacem jocul și inițializăm nivelul.
super.initialize (); CitrusEngine.getInstance (). Joc = adevărat;
Următorul cod pornește motorul Box2D care gestionează fizica motorului Citrus.
caseta var2D: Box2D = nou Box2D ("Box2d"); add (Box2D); //box2D.visible = true; // necomentați pentru a vedea grafica de depanare a Box2D
Aceste linii vor crea întregul nivel, citiți codul pentru a înțelege sistemul de instanțiere Citrus Engine (ceea ce este foarte ușor!).
(Toate vedere
proprietățile sunt numele de clasă ale simbolurilor din Biblioteca FLA: Bg
, TerrainPart1
, WaterX3
, etc)
var leftWall: platformă = platformă nouă ("LeftWall", lățime: 1, înălțime: 280, x: 0, y: 110); add (leftWall); var rightWall: Platformă = platformă nouă ("RightWall", lățime: 1, înălțime: 280, x: 726, y: 100); add (rightWall); var bg: CitrusSprite = noul CitrusSprite ('Bg', view: Bg, x: 0, y: 20); add (bg); var terrain1: platformă = platformă nouă ('Terrain1', lățime: 422, înălțime: 32, x: 211, y: 264, vedere: TerrainPart1); add (terrain1); var oneWay1: Platformă = platformă nouă ("OneWay1", lățime: 92, înălțime: 32, x: 184, y: 232, o dată: adevărată, vizualizare: OneWay1); add (oneWay1); var gem: Monedă = monedă nouă ("Gem", lățime: 11, înălțime: 10, x: 186, y: 136, vedere: Gem); add (bijuterie); var apă: senzor = senzor nou ("Apă", lățime: 92, înălțime: 32, x: 468, y: 264, vedere: WaterX3); adaugă apă); var terrain2: platformă = platformă nouă ("Terrain2", lățime: 214, înălțime: 32, x: 621, y: 264, vedere: TerrainPart2); add (terrain2); var baddy: Baddy = nou Baddy ("Baddy", x: 300, y: 200, leftBound: 250, rightbound: 350, view: Enemy); add (baddy); var movingPlatform: MovingPlatform = MovingPlatform nou ('MP', lățime: 32, înălțime: 8, x: 436, y: 232, startX: 436, startY: 232, : 0,9); add (movingPlatform); var oneWay2: platformă = platformă nouă ("OneWay2", lățime: 127, înălțime: 32, x: 663, y: 232, una Ceva: adevărat, vizualizare: OneWay2); add (oneWay2); var oneWay3: platformă = platformă nouă ("OneWay3", lățime: 64, înălțime: 32, x: 695, y: 200, oneWay: true, vizualizare: OneWay3); add (oneWay3); var: senzor = senzor nou ("ușă", lățime: 20, înălțime: 28, x: 695, y: 202, vedere: ușă); add (ușă); erou = erou nou ("Hero", x: 30, y: 234, lățime: 19, înălțime: 26, vedere: HeroClip, jumpHeight: 9, maxVelocity: 2, hurtVelocityX: 2); add (erou);
După cum puteți vedea, în fiecare caz creați o instanță a tipului de obiect pe care îl doriți și utilizați parametrii pentru a specifica poziția, dimensiunea, grafica sau pielea (aceasta este vedere parametru) și alte elemente utile. Apoi îl adăugăm la faza Citrus folosind adăuga()
metodă.
Să ne oprim aici pentru a face un test rapid și a ne asigura că codul nostru de joc funcționează:
Amintiți-vă că Milestone-urile sunt incluse în fișierele sursă, deci dacă dintr-un anumit motiv fișierul dvs. nu imită acest lucru, aruncați o privire la sursă pentru a vedea ce poate cauza acest lucru. (Și rețineți că unele linii trebuie să fie comentate deoarece unele funcții nu au fost încă create.)
Citrus Engine utilizează semnale pentru a face față interacțiunii tipului de eveniment. Puteți afla mai multe despre semnalele din acest tutorial Activetuts +.
gem.onBeginContact.addOnce (funcția (e: *) gemSnd.play (); scoreTF.text = String (int (scoreTF.text) + 50);); door.onBeginContact.addOnce (levelComplete); hero.onTakeDamage.add (hurtHero); hero.onGiveDamage.addOnce (killBaddy); hero.onJump.add (function () jumpSnd.play ()); hero.onGiveDamage.addOnce (function () baddySnd.play ());
Eroul nostru MovieClip se va juca în mod prestabilit, dacă nu îl împiedicăm. Acest cod se ocupă de acest lucru și veți învăța, de asemenea, cum să accesați filmulețul care servește drept artă pentru Obiectul dvs. Citrus.
this.view.getArt (erou) .content.stop (); //State(Level).SpriteView.SpriteArt.MovieClip.stop gameListeners (); addIndicators ();
Acest cod adaugă ascultătorii EnterFrame și Keyboard care vor fi utilizați în jocul nostru. Puteti citi despre functiile corespunzatoare de manipulare in urmatorii pasi.
funcția finală privată de jocListeners (acțiune: String = 'add'): void if (action == 'add') stage.addEventListener (Event.ENTER_FRAME, gameLogic); stage.addEventListener (tastaturăEvent.KEY_DOWN, animateWalk); stage.addEventListener (tastaturăEvent.KEY_UP, stopWalk); altceva stage.removeEventListener (Event.ENTER_FRAME, gameLogic); stage.removeEventListener (tastaturăEvent.KEY_DOWN, animateWalk); stage.removeEventListener (tastaturăEvent.KEY_UP, stopWalk);
Inimile vor reprezenta sănătatea eroului nostru. Următorul cod adaugă trei inimi la scenă și le stochează într-un Vector pentru a le folosi ulterior în afara acestei funcții.
funcția finală privată addIndicators (): void / * Hearts * / pentru (var i: int = 0; i < 3; i++) var heart:Heart = new Heart(); heart.y = 5; heart.x = 5 + (i * heart.width); addChild(heart); hearts.push(heart);
Scorul TextField este creat de acest cod. Folosim filtre pentru a adăuga cursa neagră în jurul literelor.
/ * Scor * / scorTF.x = 320; scoreTF.defaultTextFormat = tf; scoreTF.text = '0'; var filtru: BitmapFilter = nou GlowFilter (0, 1, 2, 2); var filtru2: BitmapFilter = nou GlowFilter (0, 1, 1, 1); scoreTF.filters = [filtru, filtru2]; addChild (scoreTF);
Aici am instalat aparatul foto, care va urma eroul nostru dacă poziția sa este trecută de centrul X al scenei.
funcția privată finală gameLogic (e: Event): void / * Handle Camera * / if (hero.x> = stage.stageWidth * 0.5) view.setupCamera (erou, new MathVector (stage.stageWidth * 0.5, 234); nou dreptunghi (0, 0, 726, 228), null);
Acest cod verifică dacă eroul nostru a căzut în apă și, dacă este așa, joacă pierderea sunetului și sună o alertă.
/ * Verificați dacă eroul a căzut * / dacă (hero.y> stage.stageHeight) loseSnd.play (); alert ( 'pierd');
Animația noastră de mers pe jos de erou este pornită când se apasă tastele săgeată stânga sau dreapta.
funcția finală privată animateWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (eroul) .content.play ();
La eliberarea tastelor, animația se oprește.
funcția finală privată stopWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (eroul) .content.gotoAndStop (1);
Să ne oprim aici pentru a face un alt test și pentru a verifica dacă codul nostru de joc funcționează:
Rețineți din nou că unele linii au fost comentate deoarece nu toate funcțiile au fost create încă.
Amintiți-vă că Milestone-urile sunt incluse în fișierele sursă, așa că dacă dintr-un anumit motiv fișierul dvs. nu imită acest lucru, aruncați o privire la sursă pentru a vedea ce ar putea provoca.
Eroul ar trebui să se deterioreze dacă hoțul îl atinge; următoarele linii elimină o inimă și joacă sunetul rănit. O alertă este chemată atunci când eroul este în afara sănătății.
funcția finală privată hurtHero (): void removeChild (inimile [hearts.length-1]); hearts.splice (inimile-lungime-1, 1); hitSnd.play (); în cazul în care (hearts.length <= 0) loseSnd.play(); alert('lose');
Poți ucide un nebun sărind pe el. Când se întâmplă acest lucru, scorul crește.
funcția finală privată killBaddy (): void scoreTF.text = String (int (scoreTF.text) + 100);
Nivelul se termină când eroul ajunge la ușă. Va fi redat un sunet și va fi anunțată o alertă; puteți vedea codul de alertă în pasul următor.
funcția finală privată finalăComplet (e: *): void goalSnd.play (); alerta();
Această funcție va opri jocul și va afișa jocul peste mesaj și va adăuga, de asemenea, un ascultător al mouse-ului pentru a reseta jocul atunci când a făcut clic.
alertă privată finală a funcției (gameState: String = 'win'): void gameListeners ('rmv'); CitrusEngine.getInstance (). Joc = fals; this.view.getArt (erou) .content.gotoAndStop (1); var alert: AlertView = nou AlertView (); alert.x = stage.stageWidth * 0.5; alert.y = stage.stageHeight * 0.5; alert.scoreTF.text = scoreTF.text; alert.addEventListener (MouseEvent.MOUSE_UP, reporniți); dacă (gameState == 'pierde') alert.titleTF.text = 'Nivelul a eșuat!'; addChild (alertă); TweenNano.from (alertă, 0.6, scaleX: 0.2, scaleY: 0.2, ease: Expo.easeOut);
Acest cod va reîncărca SWF când se face clic pe mesajul de joc, restabilind toate valorile inițiale și revenind la ecranul inițial.
reinițializare finală a funcției finale (e: MouseEvent): void navigateToURL (nou URLRequest (stage.loaderInfo.url), '_level0');
Suntem gata să facem un test final la jocul nostru și să verificăm că totul funcționează așa cum era de așteptat.
Experimentați acest motor puternic de joc și creați propriile jocuri!
Sper că ți-a plăcut acest tutorial, mulțumesc pentru lectură!