StartTutorialsGame MakerSchachbrett zeichnen in GML

Schachbrett zeichnen in GML

  • 6 Monaten her
  • 10Minuten

Das wird ein etwas längeres Coding-Tutorial. Ich möchte einen Weg zeigen, wie man im GML ein Schachbrett mit Figuren zeichnet. Dabei sollen Brett und Figuren ausgetauscht werden können und das Brett wird auf zwei Seiten beschriftet. Außerdem gibt es die Möglichkeit, das Brett um 180° zu drehen.

Natürlich lassen sich auch andere Figuren einsetzen, etwa Dame. Die Logik dahinter ist die selbe. Die auftretenden Probleme lösen wir mit eindimensionalen Arrays. Das hat gleich mehrere Gründe:

  1. In GML wurden 2D-Arrays intern auf 1D umgestellt.
  2. 1D-Arrays sind i. d. R. schneller als 2D-Arrays.
  3. Wenn wir auf GM-Eigene Befehle wie DS-List, DS-Map etc. verzichten, können wir den Code einfacher in eine andere Programmiersprache übersetzen, falls nötig.

Das Resultat soll so aussehen:

Schachbrett Setting
Schachbrett Setting

Ausgangszustand und Ressourcen

Wir erstellen ein neues Projekt. Den Raum habe ich ChessboardSettings genannt. Er hat die Größe von 1080×1920, ist von der Ausrichtung her also eher für Mobile gedacht. Dies lässt sich aber beliebig anpassen.

Die Zahl der Objekte lässt sich auf eins reduzieren. Bei mir heißt es obj_ChessboardSettings.

Meine Schrift heißt fnt_boart_letter. Die brauchen wir, um das Brett zu beschriften. Hier verwende ich Regular in der Größe 16.

Außerdem brauchen wir noch sechs Sprites, die bei mir wie folgt benannt sind:

Schachbrett Sprites 1
Schachbrett Sprites 1

Wie man sehen kann, gibt es nur das Icon für das Schachbrett. Die Farben zeichnen wir im Code.

Infos zu den Sprites

Die Pfeile brauchen wir zum durchschalten. Hätte ich bei der Grafik keinen Lichteffekt verwendet, hätte sogar ein Sprite gereicht.

spr_arrows
spr_arrows

Wir auf dem oberen Screenshot zu sehen ist, haben wir unter dem Brett noch ein Icon. Bei mir heißt es icon_chessboard:

icon chessboard
icon_chessboard

Zum Schluss haben wir noch vier Sprites mit Schachfiguren. Je zwei gehören zu einem Set, etwa spr_alpha_w und spr_alpha_b:

spr alpha w
spr_alpha_w

Wie man sehen kann, sind je sechs Figuren von einer Farbe in einem Sprite. Jede Figur hat die Maße 120×120 Pixel. Damit es gut aussieht, ist darauf zu achten, dass alle Figuren unten bündig sind und an den Seiten sowie oben etwas Platz haben, da unsere Felder ebenfalls 120×120 Pixel haben werden.

Der Code

Bevor ich die grundlegende Logik erkläre, zeige ich das Create-Event:

Zuerst definieren wir sechs Variablen. colorSet und piecesSet sagen uns, welches Set verwendet werden soll. Diese schalten wir später um. boardStep gibt die Abstände bzw. die Größe der Felder vor. Hier sehen wir wieder unsere 120 Pixel. startX und startY sind unser Ausgangspunkt zum zeichnen. Die Variable flip sagt aus, ob das Brett gedreht werden soll.

Nun zu den großen Arrays. Wenn man sie so schreibt, wie ich, erkennt man gleich, dass es jeweils 64 Werte sind, die wie ein Schachbrett angeordnet wurden (8×8). Die Anordnung dient nur der Übersicht, man hätte es auch jeweils in eine Zeile schreiben können.

board_color

Das Array board_color[] gibt für jedes Feld an, ob es hell (0) oder dunkel (1) sein soll. Hier erkennt man schon eines der Vorteile des Arrays: Man kann hier, falls gewünscht, auch andere Farbfolgen definieren. Es muss also nicht bei einem zweifarbigen Muster bleiben.

init_color

Das sagt aus, wo die Figuren zu welcher Farbe stehen. Weiß unten (1), Schwarz oben (0) und in der Mitte stehen keine Figuren (6).

init_board

Durch init_color[] wissen wir zwar, wo die Farben sind, aber nicht, welche Figur wo steht. Dafür haben wir init_board[]. 0 = Bauer, 1 = Springer, 2 = Läufer, 3 = Turm, 4 = Dame und 5 = König. 6 ist wieder ein neutrales Feld. Jetzt versteht man eher, warum bei init_color die 6 ebenfalls neutral ist.

Flip

Flip[] sieht interessant aus, aber auf die Logik dahinter gehe ich im Draw-Event ein.

Key Up-F-Event

Hier definieren wir die Drehung des Bretts.

Draw-Event

Auf den ersten Blick erschlägt einen der Code, aber ich werde ihn bei der Erklärung, wie immer, zerstückeln:

Das sind 162 Zeilen GML-Spaß. 🙂 Geübtere Leser werden zwei Dinge erkannt haben:

  1. Wir nutzen für das Brett 5 Farb-Sets.
  2. Die Farben werden in Hex-Werten angegeben, was in GML mittlerweile möglich ist. Das erlöst uns vom lästigen make_color_rgb()-Befehl.

Variablen und Font

Wir fangen mit lokalen Variablen an und definieren noch unsere Schrift für das Brett. Auf die Variablen in der ersten Zeile gehe ich gleich noch ein. Die Variable alpha brauchen wir später für den Schatten der Icons.

Brettfarben

Hier sind die fünf Sets definiert. Jedes Set verfügt über vier Farben. Eine helle (col0), eine dunkle (col1), sowie Rahmen- und Schriftfarbe (colBor, colLet). Zur Umschaltung nutzen wir eine Switch.

Figuren

Bei den Figuren gehen wir so vor wie bei den Felder, nur dass wir hier die Sprites und nicht Farben definieren. Das Prinzip der Switch bleibt gleich.

Rahmen und Brett

Zunächst schalten wir auf die Farbe des Rahmens um und zeichnen daraufhin ein Rechteck, welches zu allen Seiten 30 Pixel größer ist, als das eigentliche Brett. Dann geht es langsam an das eigentliche Brett. Je nachdem, ob das Brett gedreht wurde oder nicht, werden die Buchstaben, Reihen und Spalten definiert. Zum Ende dieses Blocks definieren wir noch horizontale und vertikale Ausrichtung der Texte. Dann geht es an die große Schleife:

Nun geht es ans Eingemachte!

Wir sehen eine große for-Schleife, die wir 64mal durchlaufen. Wenn man sich die Schleife genauer anschaut, erkennt man, dass sie sich gedanklich in vier Abschnitte unterteilen lässt. Dies wollen wir tun:

  1. Wir definieren ein paar Variablen
  2. Brett zeichnen, wenn es gedreht ist
  3. Brett zeichnen, wenn es nicht gedreht ist
  4. Irgendwas mit Zeilen und Spalten

Es wird klar, dass die Bereiche 2 und 3 nahezu identisch sind. Das macht es einfacher, die Schleife zu verstehen.

Die lokalen Variablen stepsColumn und stepsLine sind nur Zwischenberechnungen. Das ginge auch kompakter, aber wir wollen es verstehen, also steht es hier ausführlicher. Wir wir sehen, werden die Variablen coloumn und line rauf bzw. runter gezählt. Multipliziert mit boardStep (120) ergibt das eine relative Position auf dem Brett.

Bei xx und yy ziehen wir noch startX und startY hinzu, woraus eine absolute Position wird. Dann geht es auch schon ans Zeichnen.

Flip

Nun kommen wir zum mysteriösen Flip. Das Array aus dem Create-Event brauchen wir nur einmal:

Unsere for-Schleife läuft von 0 bis 63. An der Variable i orientiert sich der Part ohne Flip. Für die Brettdrehung haben wir j. Damit wir beim gedrehten Brett alles richtig zeichnen, brauchen wir das Hilfs-Array Flip[] und ziehen die entsprechende Zahl von 63 ab.

Dazu ein Beispiel: i ist bei 10. Da es bei 0 beginnt, brauchen wir den 11. Wert in Flip[]. Das ist die 50. j ist somit 63-50, also 13. Wenn man sich das Array Flip[] anschaut und die Zahlen 10 und 53 sucht, versteht man, dass die 180°-Drehung einer horizontalen und vertikalen Spiegelung entspricht.

Flip Array
Flip Array

Der Rest ist in Abschnitt 2 und 3 identisch, nur dass wir einmal j und einmal i verwenden.

Brettfarbe

Im Array board_color[] schauen wir nach, ob das Feld 0 (hell) oder 1 (dunkel) ist. Danach wird das Quadrat gezeichnet:

Beschriftung

Nun kommt die Beschriftung:

Wir nutzen die Farbe für die Beschriftung der Reihen und zeichnen den Text (1 bis 8) an der entsprechenden Stelle.

Figuren

Jetzt kommen unsere Figuren:

Hier nutzen wir gleich zwei Arrays. init_color[] sagt uns die Farbe (schwarz/weiß) und init_board[] die Art der Figur. 

Nächste Zeile, bitte

Die letzte Zeile im Block ist:

bzw.

im Block ohne Flip. Doch was tun wir hier?

Wir haben ein eindimensionales Array, wollen aber nach 8 Feldern in die nächste Zeile (yy) umschalten. Also müssen wir prüfen, ob j bzw. i durch 8 teilbar ist und wir nicht schon am Ende der Schleife sind. Wenn ja, gehen wir eine Zeile hoch bzw. runter.

Zeilen und Spalten

Jetzt sind wir im letzten Abschnitt:

Letztlich machen wir hier nichts anderes, als die Buchstaben (let[]) zu schreiben. Dabei zählen wir brav die Spalten (column) durch und setzen sie auf 0, sobald wir bei 7 sind.

Buttons und Icons

Der letzte Block im Draw-Event ist selbstredend. Hier zeichnen wir das Brett-Icon, ein Symbol für das Figuren-Set und die zugehörigen Pfeile.

Global Left Released-Event

Am Ende geht es noch um die Funktionalität. Die Pfeile werden mit der Maus bedient. Im entsprechenden Event fragen wir den Klick mit point_in_rectangle() ab und schalten die Variablen colorSet und piecesSet rauf oder runter.

Das war es auch schon wieder!

Hat Dir dieser Artikel gefallen? Dann würden wir uns sehr über Unterstützung freuen.

Sven Gramatke
Sven Gramatke//www.gravitationart.com/
Schreibt gelegentlich Artikel. Schwerpunkte sind Gamedesign, Programmierung (GML, PHP und JS), Retro und Berichte.
Abonnieren
Benachrichtige mich bei
guest

0 Comments
Inline Feedbacks
View all comments

NEWS

PDF

Artikel als PDF

0
Alle ByteGame-Artikel können nun bequem als PDF-Datei heruntergeladen werden. Diese Funktion wurde eingebaut, um vor allem längere Texte ausdrucken oder zumindest offline lesen zu...
Revision 2022

Revision 2022 – Eine Satellitenveranstaltung

0
Wer zu Ostern noch nichts vor hat, sollte über einen Besuch der Revision nachdenken. Diese Demoszene-Party startet am Karfreitag, den 15. April und endet...
news logo 696x400

Revorix Update 1.9

1
Revorix hat ein neues Update bekommen: Patch 1.9 Hauptfeature sind Ressourcen-Events mit der Möglichkeit wechselnde Ressourcen spenden zu können gegen noch zu enthüllende Überraschungen. Außerdem...
news logo 696x400

Godot 3.4.2 veröffentlicht

0
Kurz nach Version 3.4.1 wurde schon 3.4.2 der Spieleengine veröffentlicht. Grund für das schnelle Update war ein Fehler. Bein Rendering unter macOS konnte es...
news logo 696x400

CRYENGINE 5.7 Roadmap enthüllt

0
Nach langer Wartezeit wurde nun die Roadmap für die CRYENGINE 5.7 enthüllt. Crytek räumt dabei interne Schwierigkeiten ein. Intern sind wir bei der Entwicklung auf...
0
Would love your thoughts, please comment.x