Erstellen Sie mit Citrus einen einfachen Flash-Plattformer

Wollten Sie schon immer ein Plattformprogramm erstellen, aber nicht zu sehr darauf aus, den gesamten Code von Grund auf zu schreiben? Die Citrus Engine eliminiert den Code nicht vollständig, aber er vereinfacht die Arbeit mit vielen nützlichen Funktionen für 2D-Spiele. In diesem Lernprogramm erstellen wir ein einfaches Plattformspiel.


Schritt 1: Kurzübersicht

In diesem Tutorial verwenden wir eine beliebte Flash Game Engine, genannt Citrus, und eine Reihe von ActionScript-Klassen, um ein Plattformspiel zu erstellen.


Schritt 2: Flash-Dokumenteinstellungen

Öffnen Sie Flash und erstellen Sie ein 420x280px-Dokument. Stellen Sie die Bildrate auf 30fps ein.


Schritt 3: Schnittstelle

Wir werden diese großartigen Pixelgrafiken von Guillaume Moreau verwenden. Sie können sie von opengameart.org herunterladen.


Schritt 4: Hintergrund

Ändern Sie für den Hintergrund die Bühnenfarbe in # 99D9EA oder zeichnen Sie mit dem Rechteckwerkzeug (R) ein Rechteck dieser Farbe.


Schritt 5: Alarm

Eine Warnung wird angezeigt, wenn der Spieler das Level beendet hat oder stirbt. Es wird eine Game Over-Nachricht und die Punktzahl angezeigt. Verwenden Sie die Rechteckwerkzeug erstellen Sie ihn und setzen Sie den Instanznamen auf AlertView. Markiere die Export für ActionScript und geben Sie ihm den gleichen Klassennamen.

Es gibt viele andere Objekte im Spiel (zum Beispiel: einen Titelbildschirm, die verschiedenen Symbole für jedes Sprite, das Gelände). Anstatt zu erklären, wie Sie sie hier erstellen, sollten Sie die Quelldateien herunterladen und prüfen, welche Objekte sich in der FLA-Bibliothek befinden. Sie können entweder die gleichen Symbole in Ihrem eigenen Spiel verwenden oder neue erstellen!


Schritt 6: Schrift einbetten

Wir verwenden eine Bitmap-Schriftart im Spiel. Da wir die Schriftart dynamisch verwenden, müssen wir sie in die Anwendung einbetten. Ich verwende die Schriften 04b11 und Arcade Classic.

Wählen Sie ein dynamisches Textfeld mit der von Ihnen bevorzugten Schriftart aus und klicken Sie auf Einbetten… Taste in der Eigenschaftenbereich.

Wählen Sie alle erforderlichen Zeichen aus und fügen Sie sie hinzu, und klicken Sie auf OK.


Schritt 7: Sounds

Wir werden Soundeffekte verwenden, um das Spielgefühl zu verbessern. Die in diesem Beispiel verwendeten Sounds wurden mit as3sfxr generiert und sind in den Quelldateien enthalten.


Schritt 8: TweenNano

Wir verwenden eine andere Tween-Engine als die in Flash enthaltene Standardeinstellung. Dies erhöht die Leistung und ist einfacher zu bedienen.

Sie können TweenNano von der offiziellen Website herunterladen.


Schritt 9: Citrus Engine

Wir werden die Citrus Engine verwenden, um unser Spiel anzutreiben.

Was ist die Citrus Engine? Erfahren Sie mehr von seiner Website:

Die Citrus Engine ist eine professionelle, skalierbare Flash-Spiel-Engine für Spiele in Industriequalität. Es basiert auf modernen Flash-Programmierverfahren, sodass Sie sich darauf konzentrieren können, Ihr Spiel fantastisch zu machen! Es ist mit einem "Plattform-Starter-Kit" ausgestattet, mit dem Sie auf einfache Weise fantastische 2D-Seitencrolling-Spiele erstellen können.


Schritt 10: Citrus Engine einrichten

Gehen Sie zur Downloadseite und holen Sie sich die erforderlichen Dateien. Öffnen Sie die Flash-Einstellungen und wählen Sie ActionScript aus der Liste links und klicken Sie auf ActionScript 3.0-Einstellungen… , Fügen Sie dann den Pfad zu den Quellen hinzu, wie in der Abbildung oben gezeigt.


Schritt 11: Legen Sie die Dokumentenklasse fest

Wir machen unsere Anwendung interaktiv, indem wir eine externe Klasse verwenden. Fügen Sie seinen Namen hinzu (Main) zum Klasse Feld in der Veröffentlichen Abschnitt der Eigenschaften Panel, um die FLA der Hauptdokumentklasse zuzuordnen.


Schritt 12: Erstellen Sie eine neue ActionScript-Klasse

Erstellen Sie eine neue (Cmd + N) ActionScript 3.0-Klasse, und speichern Sie sie als Main.as in Ihrem Klassenordner.


Schritt 13: Klassenstruktur

Erstellen Sie Ihre grundlegende Klassenstruktur, um mit dem Schreiben Ihres Codes zu beginnen.

 package öffentliche Klasse Main öffentliche Funktion Main (): void // constructor code

Schritt 14: Main.as

Das Main Die Klasse bereitet die Citrus Engine auf die erste Stufe vor.

 Paket import com.citrusengine.core.CitrusEngine; öffentliche Abschlussklasse Main erweitert CitrusEngine öffentliche Abschlussfunktion Main (): void super (); state = neue Ebene (); 

Diese Klasse erweitert die CitrusEngine-Klasse und setzt den Status des Spiels auf Niveau, Dies ist der Name der Klasse, die alle Verhaltensweisen unseres Spiels enthält.


Schritt 15: Level.as

Die State-Klasse ist eine der Kernklassen der Citrus Engine. Sie sollten diese Klasse erweitern, um die Spielelogik Ihrer Level oder Staaten zu erstellen. In diesem Beispiel das Niveau Klasse erweitert Zustand um das erste Level des Spiels zu erstellen.

Erstellen Sie eine neue (Cmd + N) ActionScript 3.0-Klasse, und speichern Sie sie als Level.as in Ihrem Klassenordner.


Schritt 16: Erforderliche Klassen

Dies sind die Klassen, die wir für unsere importieren müssen Niveau Klasse zu arbeiten. Das einführen Die Direktive macht extern definierte Klassen und Pakete für Ihren Code verfügbar.

 import flash.display.MovieClip; import flash.display.Sprite; import 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; import 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;

Schritt 17: Variablen

Dies sind die Variablen, die wir verwenden werden. Lesen Sie die Kommentare im Code, um mehr darüber zu erfahren. (Einige ihrer Namen sind selbsterklärend, daher gibt es keinen Kommentar.)

 private var levelView: LevelView = neue LevelView (); // Sprite aus der Bibliothek private var hero: Hero; private var herzen: Vektor. = neuer Vektor.(); private var tf: TextFormat = new TextFormat ('ArcadeClassic', 17, 0xFFFFFF, null, null, null, null, null, 'rechts'); private var scoreTF: TextField = neues TextField (); private var gemSnd: GemSnd = new GemSnd (); // Snd = Sound private var goalSnd: GoalSnd = new GoalSnd (); private var hitSnd: HitSnd = new HitSnd (); private var jumpSnd: JumpSnd = new JumpSnd (); private var loseSnd: LoseSnd = new LoseSnd (); private var baddySnd: BaddySnd = new BaddySnd ();

Schritt 18: Konstruktor

Der Konstruktor ist eine Funktion, die ausgeführt wird, wenn ein Objekt aus einer Klasse erstellt wird. Dieser Code wird als erster ausgeführt, wenn Sie eine Instanz eines Objekts erstellen. Wenn das Spiel gestartet wird, wird es als Teil der Dokumentklasse geladen.

Es ruft die notwendigen Funktionen auf, um das Spiel zu starten. Überprüfen Sie diese Funktionen in den nächsten Schritten.

 öffentliche abschließende Funktion Level (): void // Code

Schritt 19: Spiel pausieren

Wir fangen damit an, das Spiel zu pausieren. Dadurch wird verhindert, dass die Engine die Grafik hinzufügt, während das Level-View-Sprite auf der Bühne ist.

 öffentliche abschließende Funktion Level (): void super (); // Standard-Setup-Code CitrusEngine.getInstance (). playing = false; // Spiel pausieren

Schritt 20: Ebenenansicht hinzufügen

Dadurch wird der Bühne das Sprite der Ebenenansicht sowie ein Mauslistener zum Entfernen hinzugefügt.

 public function initialize () überschreiben: void / * Level Start View * / addChild (levelView); levelView.addEventListener (MouseEvent.MOUSE_UP, startLevel); 

Schritt 21: Startebene

Die nächste Funktion wird ausgeführt, wenn auf die Ebenenansicht geklickt wird, und übernimmt die Logik zum Starten des Spiels.

 private letzte Funktion startLevel (e: MouseEvent): void 

Schritt 22: Ebenenansicht entfernen

Dieser Code zerstört die Instanz von Level View.

 levelView.removeEventListener (MouseEvent.MOUSE_UP, startLevel); removeChild (levelView); levelView = null;

Schritt 23: Starten Sie GameState (Unpause)

Jetzt pausieren wir das Spiel und initialisieren das Level.

 super.initialize (); CitrusEngine.getInstance (). Playing = true;

Schritt 24: Starten Sie Box2D

Mit dem folgenden Code wird die Box2D-Engine gestartet, die die Physik der Citrus Engine behandelt.

 var box2D: Box2D = neue Box2D ('Box2d'); add (box2D); //box2D.visible = true; // unkommentiert, um die Debug-Grafiken von Box2D zu sehen

Schritt 25: Fügen Sie Grafikobjekte hinzu

Diese Zeilen bilden die gesamte Ebene, lesen Sie den Code durch, um das Instantiierungssystem der Citrus Engine zu verstehen (was wirklich einfach ist!).

(Alles Aussicht Eigenschaften sind die Klassennamen von Symbolen aus der FLA-Bibliothek: Bg, TerrainPart1, WaterX3, usw.)

 var leftWall: Plattform = neue Plattform ('LeftWall', width: 1, height: 280, x: 0, y: 110); add (leftWall); var rightWall: Plattform = neue Plattform ('RightWall', width: 1, height: 280, x: 726, y: 100); add (rechteWand); var bg: CitrusSprite = new CitrusSprite ('Bg', view: Bg, x: 0, y: 20); add (bg); var terrain1: Plattform = neue Plattform ('Terrain1', width: 422, height: 32, x: 211, y: 264, Ansicht: TerrainPart1); add (terrain1); var oneWay1: Plattform = neue Plattform ('OneWay1', width: 92, height: 32, x: 184, y: 232, oneWay: true, Ansicht: OneWay1); add (oneWay1); var gem: Münze = neue Münze ('Edelstein', Breite: 11, Höhe: 10, x: 186, y: 136, Ansicht: Edelstein); addieren (Edelstein); var water: Sensor = neuer Sensor ('Wasser', Breite: 92, Höhe: 32, x: 468, y: 264, Ansicht: WaterX3); Wasser hinzufügen); var terrain2: Plattform = neue Plattform ('Terrain2', width: 214, height: 32, x: 621, y: 264, Ansicht: TerrainPart2); add (terrain2); var baddy: Baddy = new Baddy ('Baddy', x: 300, y: 200, leftBound: 250, rightBound: 350, view: Enemy); addieren (Baddy); var movingPlatform: MovingPlatform = neue MovingPlatform ('MP', width: 32, height: 8, x: 436, y: 232, startX: 436, startY: 232, endX: 500, endY: 232, Ansicht: PlatformClip, Geschwindigkeit 0,9; add (movingPlatform); var oneWay2: Plattform = neue Plattform ('OneWay2', width: 127, height: 32, x: 663, y: 232, oneWay: true, view: OneWay2); addiere (oneWay2); var oneWay3: Plattform = neue Plattform ('OneWay3', width: 64, height: 32, x: 695, y: 200, oneWay: true, Ansicht: OneWay3); addiere (oneWay3); var door: Sensor = neuer Sensor ('Door', width: 20, height: 28, x: 695, y: 202, view: Door); hinzufügen (Tür); Held = neuer Held ('Hero', x: 30, y: 234, Breite: 19, Höhe: 26, Ansicht: HeroClip, jumpHeight: 9, maxVelocity: 2, hurtVelocityX: 2); addieren (Held);

Wie Sie sehen, erstellen Sie in jedem Fall eine Instanz des gewünschten Objekttyps und verwenden die Parameter, um seine Position, Größe, Grafik oder Skin anzugeben (dies ist der Aussicht Parameter) und andere nützliche Elemente. Dann fügen wir es dem Citrus-Stadium hinzu hinzufügen() Methode.

Lass uns hier einen kurzen Test machen und sicherstellen, dass unser Code funktioniert:

Denken Sie daran, dass die Meilensteine ​​in den Quelldateien enthalten sind. Wenn Ihre Datei aus irgendeinem Grund nicht imitiert, werfen Sie einen Blick auf die Quelle, um herauszufinden, was die Ursache sein kann. (Und beachten Sie, dass einige Zeilen auskommentiert werden müssen, da einige Funktionen noch nicht erstellt wurden.)


Schritt 26: Signale hinzufügen

Die Citrus Engine verwendet Signale, um die Interaktion mit Ereignistypen zu behandeln. In diesem Activetuts + -Tutorial erfahren Sie mehr über Signale.

 gem.onBeginContact.addOnce (Funktion (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 ());

Schritt 27: Heldenanimation stoppen

Unser Hero MovieClip wird standardmäßig abgespielt, sofern wir dies nicht verhindern. Dieser Code behandelt das und Sie erfahren auch, wie Sie auf den MovieClip zugreifen können, der als Grafik für Ihr Citrus-Objekt dient.

 this.view.getArt (hero) .content.stop (); //State(Level).SpriteView.SpriteArt.MovieClip.stop gameListeners (); addIndicators ();

Schritt 28: Game Listeners

Dieser Code fügt EnterFrame- und Keyboard-Listener hinzu, die in unserem Spiel verwendet werden. In den nächsten Schritten können Sie die entsprechenden Handlerfunktionen nachlesen.

 private letzte Funktion gameListeners (action: String = 'add'): void if (action == 'add') stage.addEventListener (Event.ENTER_FRAME, gameLogic); stage.addEventListener (KeyboardEvent.KEY_DOWN, animateWalk); stage.addEventListener (KeyboardEvent.KEY_UP, stopWalk);  else stage.removeEventListener (Event.ENTER_FRAME, gameLogic); stage.removeEventListener (KeyboardEvent.KEY_DOWN, animateWalk); stage.removeEventListener (KeyboardEvent.KEY_UP, stopWalk); 

Schritt 29: Herzen hinzufügen

Herzen repräsentieren die Gesundheit unseres Helden. Der nächste Code fügt der Bühne drei Herzen hinzu und speichert sie in einem Vektor, um sie später außerhalb dieser Funktion zu verwenden.

 private letzte Funktion addIndicators (): void / * Hearts * / for (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); 

Schritt 30: Score hinzufügen

Das Score-Textfeld wird durch diesen Code erstellt. Wir verwenden Filter, um die Buchstaben um den schwarzen Strich zu fügen.

 / * Score * / scoreTF.x = 320; scoreTF.defaultTextFormat = tf; scoreTF.text = '0'; var filter: BitmapFilter = neuer GlowFilter (0, 1, 2, 2); var filter2: BitmapFilter = neuer GlowFilter (0, 1, 1, 1); scoreTF.filters = [filter, filter2]; addChild (scoreTF); 

Schritt 31: Kamera handhaben

Hier stellen wir die Kamera auf, die unserem Helden folgt, wenn seine Position hinter dem Mittelpunkt X der Bühne liegt.

 private letzte Funktion gameLogic (e: Event): void / * Handle Camera * / if (hero.x> = stage.stageWidth * 0.5) view.setupCamera (hero, neuer MathVector (stage.stageWidth * 0.5, 234), neues Rechteck (0, 0, 726, 228), null); 

Schritt 32: Auf Fall prüfen

Dieser Code prüft, ob unser Held ins Wasser gefallen ist, und wenn dies der Fall ist, spielt er den Verlustton und ruft eine Warnung aus.

 / * Überprüfe, ob der Held gefallen ist * / if (hero.y> stage.stageHeight) loseSnd.play (); Alarm ('verlieren'); 

Schritt 33: Heldenwanderung animieren

Unsere Helden-Walking-Animation wird gestartet, wenn die linke oder rechte Pfeiltaste gedrückt wird.

 private letzte Funktion animateWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (hero) .content.play (); 

Schritt 34: Stop Walk Animation

Wenn die Tasten losgelassen werden, stoppt die Animation.

 private letzte Funktion stopWalk (e: KeyboardEvent): void if (e.keyCode == 37 || e.keyCode == 39) this.view.getArt (hero) .content.gotoAndStop (1); 

Lassen Sie uns hier anhalten, um einen weiteren Test durchzuführen und zu überprüfen, ob unser Code funktioniert:

Beachten Sie erneut, dass einige Zeilen auskommentiert wurden, da noch nicht alle Funktionen erstellt wurden.

Denken Sie daran, dass die Meilensteine ​​in den Quelldateien enthalten sind. Wenn Ihre Datei aus irgendeinem Grund nicht imitiert, werfen Sie einen Blick auf die Quelle, um herauszufinden, was dies möglicherweise verursacht.


Schritt 35: Verletzter Held

Der Held sollte Schaden nehmen, wenn der Baddy ihn berührt. Die nächsten Zeilen entfernen ein Herz und spielen den verletzten Sound. Ein Alarm wird ausgelöst, wenn der Held nicht mehr gesund ist.

 private letzte Funktion hurtHero (): void removeChild (hearts [hearts.length-1]); hearts.splice (hearts.length-1, 1); hitSnd.play (); if (Herzen.Länge <= 0)  loseSnd.play(); alert('lose');  

Schritt 36: Baddy töten

Sie können einen Baddy töten, indem Sie darauf springen. Wenn dies geschieht, erhöht sich die Punktzahl.

 private letzte Funktion killBaddy (): void scoreTF.text = String (int (scoreTF.text) + 100); 

Schritt 37: Level abgeschlossen

Das Level endet, wenn der Held die Tür erreicht. Es wird ein Ton abgespielt und ein Alarm ausgelöst. Sie können den Benachrichtigungscode im nächsten Schritt sehen.

 private letzte Funktion levelComplete (e: *): void goalSnd.play (); warnen(); 

Schritt 38: Alarm

Diese Funktion stoppt das Spiel und zeigt das Spiel über der Nachricht an. Außerdem wird ein Mauslistener hinzugefügt, um das Spiel zurückzusetzen, wenn Sie darauf klicken.

 private letzte Funktionswarnung (gameState: String = 'win'): void gameListeners ('rmv'); CitrusEngine.getInstance (). Playing = false; this.view.getArt (hero) .content.gotoAndStop (1); var alert: AlertView = new AlertView (); alert.x = stage.stageWidth * 0,5; alert.y = stage.stageHeight * 0.5; alert.scoreTF.text = scoreTF.text; alert.addEventListener (MouseEvent.MOUSE_UP, Neustart); if (gameState == 'lose') alert.titleTF.text = 'Stufe fehlgeschlagen!';  addChild (Warnung); TweenNano.von (Warnung, 0,6, scaleX: 0,2, scaleY: 0,2, Leichtigkeit: Expo.easeOut); 

Schritt 39: Starten Sie neu

Dieser Code lädt die SWF-Datei erneut, wenn auf die Game Over-Nachricht geklickt wird. Dabei werden alle Anfangswerte wiederhergestellt und der Ausgangsbildschirm angezeigt.

 private letzte Funktion restart (e: MouseEvent): void navigateToURL (neue URLRequest (stage.loaderInfo.url), '_level0'); 

Schritt 40: Abschließender Test

Wir sind jetzt bereit, unser Spiel abschließend zu testen und zu überprüfen, ob alles wie erwartet funktioniert.


Fazit

Experimentieren Sie mit dieser leistungsstarken Spiel-Engine und erstellen Sie Ihre eigenen Spiele!

Ich hoffe, Ihnen hat dieses Tutorial gefallen, vielen Dank für das Lesen!