Construct2 Anfänger-Tutorial
Der folgende Text basiert auf dem Beginner's Guide to Construct 2, der ursprünglich von Ashley veröffentlicht wurde.
Eine spielbare Version ist unter https://www.scirra.com/demos/ghosttutorial/ zu finden.
Ich gehe in dem Text davon aus, dass die Free-Version von Construct2 installiert ist, und zwar in Release 119. Der Hinweis auf das Release kann wichtig sein, da Construct2 sehr intensiv weiterentwickelt wird.
Neues Projekt
Im ersten Schritt erstellen wir ein Projekt, dazu klickt man entweder auf New im Files-Menü, oder auf New Project im Arbeitsbereich. Es öffnet sich ein Popup-Fenster, in dem man die Art des Projektes festlegen kann, wir wählen den ersten Eintrag New empty project. Nach einem Klick auf den Button Open öffnet sich das neue Projekt.
Im Properties-Bereich sieht man jetzt die Eigenschaften des Projektes. Hier können wir gleich einmal einen Namen festlegen.Dazu klick man auf das Feld hinter Name, wo anfangs New project steht. Dies ersetzen wir durch Anfangsprojekt. Sowie man Enter gedrückt hat ändert sich auch die entsprechende Bezeichnung rechts vom Arbeitsbereich.
Im Arbeitsbereich sind jetzt drei Tabs vorhanden, einmal der schon bekannte Tab Start page und dann Layout1 und Event sheet1. Für die folgenden Schritte ist wichtig, dass erst einmal der Tab Layout1 aktiv ist.
Man sollte sein Construct2-Projekt in regelmäßigen Abständen sichern, auch Construct2 stürzt gelegentlich ab. Dazu wählt man im Files-Menü den Punkt Save As a single file, dann wird das Projekt in einer Datei mit der Endung .capx gespeichert.
Objekte einfügen
Unser Spiel soll einen Hintergrund bekommen, der sich aus mehreren relativ kleinen Kacheln zusammensetzt, das spart Speicherplatz. Eine entsprechende Grafik stellt Scirra zur Verfügung. Einfach mit der rechten Maustaste auf die Grafik klicken und aus dem Kontext-Menü Speichern auswählen um die Grafik auf der eigenen Festplatte zu speichern.
Zum Einfügen der Grafik in das neue Projekt klickt man doppelt in einen freien Bereich im Tab Layout1, oder man klickt mit der rechten Maustaste und wählt dann Insert new object.
Es öffnet sich ein neues Fenster, in dem man Tiled Background (gekachelter Hintergrund) mit einem Doppelklick auswählt.
Der Cursor verändert sich zu einem dünnen Kreuz. Damit klickt man irgendwo in den mittleren Bereich von Layout1, worauf sich der Textur-Editor öffnet.
Hier wählt man die Funktion Load an image from a file, worauf der Datei-Dialog von Windows erscheint, über den man die zuvor heruntergeladene Grafik auswählt.
Danach kann man das Fenster des Textur-Editors schließen, indem man auf das X rechts oben im Fenster klickt. Wir sehen jetzt das Bild im Layout-Bereich und müssen es jetzt noch positionieren und skalieren.
Im Eigenschafts-Bereich (Object Type Properties) setzen wir die Position auf 0,0 (entspricht links oben im Layout) und die Größe auf 1280, 1024.
Wenn man jetzt aus dem Menü View die Funktion zoom out wählt (ggf. mehrfach), dann kann man erkennen, dass der komplette Arbeitsbereich jetzt von dem Hintergrundbild bedeckt ist, man kann sogar die einzelnen Kacheln erkennen.
Um zur normalen Skalierung zurück zu kehren wählt man aus dem Menü View den Punkt Zoom to 100%.
Wer ein bisschen ungeduldig ist, der kann an dieser Stelle schon einmal auf das Icon run in der Fensterzeile klicken, worauf sich der Browser öffnet (welcher das sein soll kann man in den Projekt-Einstellungen festlegen), der aber bisher nur das Hintergrund-Bild anzeigen kann. Immerhin!
Ebenen einfügen
Im nächsten Schritt wollen wir weitere Objekte einfügen, wir wollen das Hintergrund-Bild dabei aber nicht mehr verändern. Dazu können wir die Ebene mit dem Hintergrundbild sperren und alle weiteren Objekte in eine neue Ebene legen.
Um mit Ebenen arbeiten zu können klickt man rechts im Fenster auf den Tab Layers, der neben dem momentan aktiven Tab Projects zu finden ist.
Momentan gibt es dort nur eine Ebene mit dem Namen Layer0. Diese Ebene benennen wir erst einmal um indem wir auf das Icon mit dem Stift klicken. Wir geben der Ebene den Namen Background, sie stellt ja unseren Hintergrund dar.
Nun erzeugen wir eine weitere Ebene, indem wir auf das kleine Pluszeichen klicken und nennen die neue Ebene Main. Anschließend klicken wir auf das kleine Schlossicon neben dem Namen Background, wodurch die Ebene gegen Bearbeitung gesichert wird. Man kann diese Sperre natürlich jederzeit auch wieder aufheben, indem man erneut auf das nun geschlossene Schloss klickt.
Nun sollte das Ebenen-Fenster folgendermaßen aussehen.
Für die nächsten Schritte ist wichtig, dass die Ebene Main wie im Bild als aktiv gekennzeichnet ist, im Zweifelsfall noch einmal anklicken im Layers-Tab.
Eingabe-Objekte
Nun wieder zurück in den Bereich Layout. Wir wollen hier je ein Objekt für die Steuerung per Tastatur und per Maus einfügen. Dazu Doppelklickt man in den Bereich Layout und wählt das Object Keyboard. Nach einem erneuten Doppelklick wählt man das Objekt Mouse.
Man sieht hier erst einmal keine Veränderung, die wäre aber im Tab Projects zu erkennen. Die eingefügten Objekte erlauben es auf Tastatur- und Mausereignisse zu reagieren.
Spiel-Objekte
Im nächsten Schritt wollen wir die Spielfiguren einfügen. das sind vier Objekte. Diese vier Objekte kann man jeweils auf seiner lokalen Festplatte speichern (Rechtsklick - Grafik speichern unter...).
Diese Objekte müssen nun noch in das Spiel integriert werden. Das geht jeweils in folgenden Schritten:
- Doppelklick in Layout1, es öffnet sich Insert New Object.
- Doppelklick auf Sprite (im Bereich General).
- Der Mauszeiger wird zum dünnen Kreuz und zeigt den Tooltip Main, einfach in einen freien Bereich in Layout1 klicken.
- Der Textur-Editor erscheint, man klickt auf das Icon Load an Image from a file, worauf der Dateiauswahldialog erscheint und jeweils eine Grafik ausgewählt werden kann.
- Den Editor schließen über das X recht oben im Fenster. Das Objekt sollte jetzt im Layout sichtbar sein.
Hinweis: Man kann die Sprite-Objekte auch einzeln per Drag & Drop aus einer anderen Anwendung in den Layout-Bereich ziehen. Construct2 erzeugt dann automatisch ein Sprite-Objekt daraus.
Das Bullet-Objekt und das Explosion-Objekt sollte man außerhalb der Layout-Fläche positionieren, so sollen ja zu Beginn nicht sichtbar sein, sondern erst bei Bedarf. Dummerweise benennt Construct2 die Objekte nicht nach ihren Dateinamen, sondern fortlaufend Sprite, Sprite2, Sprite3 und Sprite4.
Wir benennen die Objekte um, indem wir sie jeweils einmal anklicken und damit aktivieren und dann im Properties-Bereich den Namen ändern zu Player, Monster, Bullet, Explosion.
Verhalten hinzufügen
Bisher ist alles was wir erzeugt haben starr, es gibt keinerlei Einflussmöglichkeiten auf unsere Welt. Construct2 stellt einige Funktionen zur Verfügung, um die Welt zu animieren. Man kann Objekten als behavior solid zuordnen, ideal für feste Untergründe oder z.B. Platform, wie man es für viele Jump and Run Spiele haben möchte.
Die folgenden Verhalten sind für uns erst einmal interessant:
- 8Direction movement: Das Objekt kann mit den Pfeiltasten gerade und schräg bewegt werden, ideal für Spielerfiguren.
- Bullet movement: Das Objekt bewegt sich im vorgegebenen Winkel einfach geradeaus, nicht nur für Kugeln, sondern auch für Monster geeignet, die Geschwindigkeit ist einstellbar.
- Scroll to: Lässt den Bildschirm dem Objekt folgen, wichtig für die Spielerfigur.
- Bound to layout: das Objekt kann den vorgegebenen Layout-Bereich nicht verlassen, stößt also an eine virtuelle Wand.
- Destroy outside layout: Das Objekt wird am Rande der Welt nicht gestoppt, sondern zerstört. Nützlich vor allem für Geschosse.
- Fade: Das Objekt wird ausgeblendet, nützlich für Explosionen.
Nun soll Bewegung ins Spiel kommen, zuerst das 8 direction movement für den Player.
Dazu aktiviert man den Spieler durch einfaches Anklicken. In seinem Properties-Bereich findet sich die Zeile Add/Edit Edit behaviors. Hier klickt man auf Behaviors. Es öffnet sich der Kasten Behaviors.
In dem Kasten Behaviors klickt man auf das Pluszeichen und kann im folgenden Fenster ein Verhalten auswählen.
Ein Doppelklick auf 8 Direction wählt das entsprechende Verhalten aus. Der Spieler braucht aber noch weitere Behaviors, wir fügen noch ScrollTo und BoundToLayout auf die gleiche Art hinzu.
Des Fenster Player: Behaviors sollte danach folgendermaßen aussehen.
Wenn man das Spiel jetzt über das Icon run erneut startet, dann kann man die Spielfigur immerhin schon über das Spielfeld führen, aber nicht darüber hinaus.
Entsprechend setzen wir jetzt Verhalten für die übrigen Elemente:
- Bullet Objekt: Bullet movement und Destroy outside layout
- Monser: Bullet movement
- Explosion Objekt: Fade
Wenn man das Spiel jetzt erneut startet, dann wir man nur feststellen, dass das Monster relativ schnell aus dem Spiel verschwindet. Das kann man etwas verändern, indem man bei den Properties des Monsters die Eigenschaft Speed von 400 auf z.B. 80 verringert (die Angabe gibt an, um wieviele Pixel sich das Objekt in der Sekunde bewegt). Wenn man schon dabei ist, dann kann man entsprechend die Geschwindigkeit des Bullet Objektes von 400 auf 600 erhöhen und für das Explosion-Objekt die Eigenschaft Fade out time auf 0.5 setzen.
Mehrere Monster erzeugen
Das eine Monster ist für unseren Spieler keine Herausforderung, zumal es immer noch verschwindet und dem Spieler nichts tut. Wir können von der Klasse Monster ganz einfach mehrere Instanzen erzeugen, indem wir die Taste Strg festhalten, das Monster mit der linken Maustaste anklicken und mit gedrückter Maustaste die Kopie an eine neue Position ziehen.
Auf diese Art erzeugen wir 8 Monster, die am Anfang aber nicht zu dicht am Spieler sein sollten, damit der auch eine Chance hat.
Das Spielfeld könnte jetzt folgendermaßen aussehen.
Ereignisse
Nun sollen die verschiedenen Objekte (bzw. Objektklassen) auch miteinander agieren können, dazu dienen die Ereignisse. Ereignisse werden nicht im Tab Layout1 des Arbeitsbereiches untergebracht, sondern im Tab Event sheet1. Klickt man jetzt auf den Tab Event sheet 1, so ist der Bereich nahezu leer.
Ereignisse bestehen immer aus einer Bedingung und dann einer oder mehrerer Aktionen. Ein Ereignis kann sein Leertaste gedrückt oder auch Kollision einer Kugel mit einem Monster. Als Aktion kommen z.B. Positionsveränderungen oder Richtungsänderungen in Frage.
Das erste Ereignis
Der Spieler soll sich immer zur Mausposition hin ausrichten (die Pfeiltasten steuern nur die Bewegung, nicht die Ausrichtung). Dazu klicken wir auf Add event, worauf sich ein Kasten öffnet.
Wir wählen hier System aus, mit einem Doppelklick, worauf sich ein weiteres Fenster öffnet, das zu System viele verschiedene Bedingungen gehören.
Hier wählen wir Every tick mit einem erneuten Doppelklick aus, damit ist die Bedingung gesetzt.
Nun fehlt noch die Aktion. Dazu klickt man auf Add action hinter der Bedingung. Es öffnet sich wieder ein neues Fenster, hier sind alle Objekte aufgeführt, mit denen Aktionen möglich sind.
Unsere Aktion soll sich auf den Player beziehen, also ein Doppelklick auf das entsprechende Objekt. Es öffnet sich jetzt ein weiteres Fenster, in dem man die passende Aktion für den Player auswählen kann.
Wir wählen hier Set angle torward position durch einen Doppeklick. Nun will Construct2 von uns die Position angegeben bekommen. Vorgabe ist 0,0 wir wollen uns aber an der Mausposition orientieren, geben hier also Mouse.X und Mouse.Y ein.
Ein Klick auf Done beendet die Definition der Action. Das Event sheet1 sieht jetzt folgendermaßen aus.
Weitere Funktionen für das Spiel
Im folgenden werden weitere Ereignisse nicht mehr so ausführlich beschrieben. Der Ablauf ist aber in allen Fällen etwa gleich:
- Doppelklick auf das Event sheet, oder ein Klick auf Add event/Add action
- Doppelklick auf das Objekt, auf das sich die condition/action bezieht
- Doppelklick auf die gewünschte condition/action
- Eingabe von Parametern, falls notwendig
Das im vorangegangenen Abschnitt aufwändig beschriebene Event ließe sich kurz darstellen als:
Condition System -> Every tick Action Player -> Set angle towards position -> X: Mouxe.X, Y: Mouse.Y
Der Spieler kann schießen
Der Spieler soll nun durch Klicken mit der Maus schießen können. Dazu muss dann ein Bullet-Objekt erzeugt werden (Spawn an object).
Condition: Mouse -> On click -> Left clicked Action: Player -> Spawn another object -> Bullet object -> Layer: 1, Image Point: 0
Das Ereignis sieht dann folgendermaßen aus.
Wenn man das Spiel jetzt ausprobiert, dann stellt man fest, dass die Kugel aus der Mitte des Players heraus erscheint und nicht aus der Spitze heraus. Das hängt mit dem image point0 zusammen, der im Mittelpunkt der Abbildung liegt. Wir müssen also einen Passenden neuen Image point erzeugen.
Dazu klicken wir den Spieler im Objects-Bereich (unten rechts) mit der rechten Maustaste aus und wählen im Kontext-Menü Edit animations.
Es öffnet sich nun wieder der Image-Editor mit dem Player im Fenster. Hier muss man jetzt das Icon Set Origin an image points aktivieren, worauf sich das Fenster Image points öffnet.
In diesem Fenster klickt man jetzt auf das Plus-Zeichen, worauf eine neue Zeile erscheint und sich der Cursor verändert. Mit dem Cursor klickt man dann auf die gewünschte Position.
Nun muss man noch die ursprüngliche Action editieren (Doppelklick darauf) um den Bezugspunkt auf image point 1 zu setzen. Jetzt erscheinen die Bullets an der richtigen Stelle.
Damit die Kugel auch Monster töten kann müssen wir folgendes Event hinzufügen.
Condition: Bullet -> On collision with another object -> Monster auswählen Action: Monster -> Destroy Action: Bullet -> Spawn another object -> Explosion, layer 1 Action: Bullet -> Destroy
Der Explosions-Effekt
Wenn man das Programm jetzt ausprobiert, dann sieht die Explosion etwas komisch aus, da sie mit einem schwarzen Hintergrund versehen ist. Um das zu ändern muss man an die Eigenschaften des Explosion-Objektes heran. Also unter Objects anklicken und dann ganz unten unter Properties im Bereich Effects den Wert von Blend mode auf Additive stellen.
Optimierung der Monster
Momentan starten alle Monster in der gleichen Richtung und verlassen das Spielfeld dann relativ schnell. Das können wir mit zwei Erweiterungen ändern.
Condition: System -> On start of Layout Action: Monster -> Set angle -> random(360)
Nun starten die Monster in unterschiedlichen zufälligen Richtungen.
Condition: Monster -> Is outside Layout Action: Monster -> Set angle torward position -> X: Player.X, Y: Player.Y
Nun drehen sich die Monster nach dem Verlassen des Spielfeldes zum Player hin und erscheinen also wieder im sichtbaren Bereich.
Momentan langt ein einziger Treffer, um ein Monster zu vernichten. Das soll im folgenden Schritt so geändert werden, dass fünf Treffer notwendig sind.
Instanzen Variablen
Um zu erreichen, dass z.B. fünf Treffer notwendig sind um ein Monster zu vernichten muss sich jedes Monster "merken" können, wie oft es getroffen wurde. Genau für diesen Zwecke sind Instanzen-Variablen gedacht.
Wir aktivieren wieder das Monster im Object-Bereich. Unter Properties findet sich dann Add/Edit Instance variables. Ein Klick darauf öffnet ein neues Fenster.
In dem neuen Fenster klicken wir auf das Plus-Zeichen und gelangen zu dem Dialog für die Eingabe der Variablen.
Wir nennen diese Variable health, sie ist vom Typ Number (Zahl) und hat den Anfangswert 5.
Nun müssen wir noch die Events anpassen. Das Monster darf also bei einem Treffer nicht sterben, sondern muss nur seine Instanzenvariable health herunter zählen.
Dazu klicken wir mit der rechten Maustaste auf die Action Monster-> Destroy und wählen aus dem Kontextmenü Replace.
Wir ersetzen dann durch.
Action: Monster -> Subtract 1 from health
Nun stirbt aber erst einmal kein Monster mehr. Wir müssen den Monstern beibringen, dass sie verschwinden sollen, wenn ihre Variable health den Wert 0 bekommen hat.
Condition: Monster -> Compare instance variable -> health, less or equal 0 Action: Monster -> Spwan another object -> Explosion, layer 1 Action: Monster -> Destroy
Spielstände
Wir wollen die Zahl der vernichteten Monster mitzählen können. Dazu brauchen wir eine globale Variable, die beim Zerstören eines Monsters hochgezählt wird. Natürlich muss der Spielstand dann auch irgendwo angezeigt werden.
Wir klicken mit der rechten Maustaste in einen leeren-Bereich bei den Events und wählen aus dem Kontext-menü Add globale variable
Es öffnet sich wieder ein Fenster in dem man den Namen Score und den Anfangswert 0 festlegt.
Die globale Variable taucht jetzt auch ganz oben im Eventsheet mit auf.
Nun müssen wir noch an der Stelle, wo das Monster vernichtet wird (wenn sein Zähler 0 erreicht), den Score hochzählen.
Action; System -> Add 1 to Score
Dieser Score muss nun auch noch irgendwo angezeigt werden.
Heads-up display (HUD)
Für die Anzeige fügen wir eine neue Ebene ein, auf der der Spielstand als Text angezeigt wird.
Zuerst erzeugen wir im Layers-Bereich ganz rechts eine neue Ebene und nennen sie HUD. Wir aktivieren diese Ebene durch Anklicken im Layers-Bereich.
Im Properties-Bereich links setzen wir bei der Ebene die Eigenschaft Parallax auf 0,0.
Nun aktivieren den Tab Layout1, Doppelklicken auf den Hintergrund und fügen dann ein Objekt Text ein, das Element wird in der linken oberen Ecke positioniert. Leider ist der Beispieltext kaum zu sehen, er ist schwarz auf dem dunklen Hintergrund und relativ klein. Wir wählen für den Text also eine hellere Farbe und eine größere Schrift.
Nun wechseln wir wieder in das Event-Sheet und erweitern den bereits vorhandenen Eintrag System -> every tick um eine Action:
Action: Text -> Set text -> "Score: " &Score
Damit wird die Textkonstante "Score: " ausgegeben und mit dem Inhalt der Variablen Score verknüpft.
Hinweis: Sollte keinerlei Text zu sehen sein, so kann das daran liegen, dass der Text hinter dem Background liegt. Die Nummer der HUD-Ebene muss größer sein, als die der Backgreound-Ebene.
Letzte Änderungen
Momentan ist es so, dass irgendwann alle Monster erledigt sind. Ab da wird das Spiel sehr langweilig. Wir lassen jetzt noch alle 3 Sekunden ein neues Monster erzeugen:
Condition: System -> Every X seconds -> 3 Action: system -> Create object -> Monster, layer1, 1400, random(1024)
Und dann soll es auch auch noch so etwas wie Gerechtigkeit geben. Der Spieler soll bei einer Kollision mit einem Monster getötet werden.
Condition: Monster -> On collision with another object -> Player Action: Player -> Destroy
Spielbare Version
http://www.scirra.com/arcade/addicting-example-games/956/memory-match-tutorial