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.
In diesem Tutorial verwenden wir eine beliebte Flash Game Engine, genannt Citrus, und eine Reihe von ActionScript-Klassen, um ein Plattformspiel zu erstellen.
Öffnen Sie Flash und erstellen Sie ein 420x280px-Dokument. Stellen Sie die Bildrate auf 30fps ein.
Wir werden diese großartigen Pixelgrafiken von Guillaume Moreau verwenden. Sie können sie von opengameart.org herunterladen.
Ändern Sie für den Hintergrund die Bühnenfarbe in # 99D9EA oder zeichnen Sie mit dem Rechteckwerkzeug (R) ein Rechteck dieser Farbe.
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!
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.
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.
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.
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.
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.
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.
Erstellen Sie eine neue (Cmd + N) ActionScript 3.0-Klasse, und speichern Sie sie als Main.as in Ihrem Klassenordner.
Erstellen Sie Ihre grundlegende Klassenstruktur, um mit dem Schreiben Ihres Codes zu beginnen.
package öffentliche Klasse Main öffentliche Funktion Main (): void // constructor code
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.
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.
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;
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 ();
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
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
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);
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
Dieser Code zerstört die Instanz von Level View.
levelView.removeEventListener (MouseEvent.MOUSE_UP, startLevel); removeChild (levelView); levelView = null;
Jetzt pausieren wir das Spiel und initialisieren das Level.
super.initialize (); CitrusEngine.getInstance (). Playing = true;
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
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.)
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 ());
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 ();
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);
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);
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);
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);
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');
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 ();
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.
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');
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);
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();
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);
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');
Wir sind jetzt bereit, unser Spiel abschließend zu testen und zu überprüfen, ob alles wie erwartet funktioniert.
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!