Sonntag, 29. Mai 2016

Mai 2016 - Schulprojekt "Vier Gewinnt"

In der Schule im Modul 306 - IT Kleinprojekt abwickeln - arbeiten wir in Gruppen an einem individuellen Projekt. Dabei geht es nicht nur rein ums Entwickeln einer Applikation, sondern auch darum, alle Arbeiten zu planen, verschiedene Berichte (Initialisierungsbericht, Konzeptbericht, Einführungsbericht etc. ...) korrekt zu verfassen und termingerecht abzugeben. Das Modul 306 soll auf die IdPA im letzten Lehrjahr vorbereiten. Wie in einem vorherigen Blogbeitrag bereits erwähnt, arbeiten wir in unserer Gruppe für das Projekt mit der Spiel-Engine Unity5.


Projekt "Vier Gewinnt"

Wir wollten in unserem Projekt den Spieleklassiker "Vier Gewinnt" als Desktopanwendung neu aufleben lassen. Wir haben uns dafür entschieden, da wir eine neue Technologie kennen lernen wollten (Unity5) und da wir als Zweiergruppe im Gegensatz zu grösseren Gruppen in der gegebenen Zeit nicht so ein umfangreiches Projekt entwickeln können. Weiterhin haben wir dort noch Möglichkeiten für Erweiterungen, falls wir doch mehr Zeit als geplant zur Verfügung gehabt hätten.
Da wir immer wieder an Dokumentationen arbeiten mussten, die wir später dann zur Bewertung abgeben sollten, konnten wir weniger Zeit als zunächst angenommen in die Realisierung des Projekts investieren. Deshalb mussten wir einige Zusatzfunktionen streichen. Die Applikation läuft nun, aber nur im Mehrspieler-Modus. Das heisst, man kann zu zweit gegeneinander "Vier gewinnt" auf einem PC spielen.
Eigentlich wollten wir anfangs noch als Zusatzfunktion einen Einzelspielermodus einbauen. Man würde dann gegen den Computer in verschiedenen Schwierigkeitsstufen antreten. Um gegen einen Computer spielen zu können, müsste man eine KI (Künstliche Intelligenz) entwickeln. Dies ist meist ein ziemlich grosses Unterfangen und hätte wohl auf keinen Fall auch noch in unser Projekt gepasst.
Auf einige kleinere Zusatzfunktionen, die eigentlich keinen wirklich grossen Nutzen gehabt hätten, haben wir verzichtet, um mehr Zeit für die Hauptfunktionen zu haben und so besser deren Funktionstüchtigkeit gewährleisten zu können.

Entwicklung

Die Entwicklung geschah wie schon erwähnt mit der Spiel-Engine Unity5 (siehe Blogeintrag Februar 2016) und der Programmiersprache C#. In Unity hätte man die Möglichkeit, Spiele in 3D zu entwickeln. Da wir aber keinen grossen Nutzen darin sahen, ein "Vier Gewinnt" in 3D zu gestalten, wollten wir es klassisch in 2D halten.
Die Anwendung besteht im Wesentlichen nur aus zwei verschiedenen Fenstern. Der Start-Screen und der Spiele-Screen. Im folgenden Bild sieht man den Spiele-Screen in der IDE:




In der Mitte des Fensters ist der Spiel-Screen zu sehen, auf der linken Seite die in dieser Szene befindlichen Objekte. Unterhalb sieht man eine Art Explorer, wo man auf seine Dateien im Projekt zugreifen kann, beispielsweise Bilder, Scripts etc. Auf der rechten Seite sieht man die Eigenschaften des Objekts.
Um Buttons verwenden zu können, wird ein sogenanntes "Canvas" über das Fenster gelegt. In diesem "Canvas" befinden sich die eigentlichen Buttons oder ähnliches wie Textboxen. Damit ein Button nun etwas macht, wenn man drauf klickt, muss man dem Button ein Script hinterlegen. Dabei wird im Script meist eine Funktion definiert die dann per Buttonklick ausgeführt wird. Hier können auch Parameter mitgegeben werden, sofern die hinterlegte Funktion das unterstützt. Scripts werden meist in Visual Studio oder dem integrierten Editor "Mono" geschrieben.
Eine Schwierigkeit, die wir hatten, da wir uns vorher noch nie mit Unity auseinander gesetzt hatten, war das Zugreifen auf Objekte (z.B. auf ein Spielstein). Da die Scripts ja eigentlich unabhängig von den einzelnen Szenen sind, kennt das Script die Objekte auch nicht einfach so. Eine Lösung für dieses Problem besteht darin, alle Objekte eindeutig zu taggen und dann mit der folgenden Unity-Funktion zu suchen::

       GameObject.FindGameObjectWithTag("objecttag")

Zusätzlich zu dieser Funktion wird dann meist eine Referenzvariable des Typs "GameObject" erstellt, die auf das mit der obenstehenden Funktion gefundene Objekt zeigt. Über diese Referenzvariable kann dann das Objekt angesprochen werden.

Eine weitere wichtige Funktion für uns war folgende:

       Instantiate(Resources.Load("path")) as GameObject

Damit kann man ein zuvor in Unity erstelltes und als sogenanntes "Prefab" gespeichertes Objekt instanziieren. Das haben wir verwendet, um jedes Mal eine neue Instanz einer der beiden zuvor erstellten Spielsteine (rot und gelb) zu erstellen, wenn ein entsprechender Spalten-Button angeklickt wird. Das bedeutet, dass dann immer bei der jeweiligen Spalte ein neuer Spielstein instanziiert wird und dann letztendlich in die gewählte Spalte fällt.

Um also seinen Stein setzen zu können, muss der Spieler auf einen der sechs Spalten-Buttons klicken. Hinter diesen Buttons befindet sich jeweils dasselbe Script mit einer Funktion, die einen Parameter erwartet - die Spaltennummer (0 bis 5).
Hat man also nun auf einen der Spalten-Buttons geklickt, wird entweder ein neuer roter oder gelber Stein instanziiert, je nachdem, wer gerade am Zug ist.
Gleichzeitig wird überprüft, ob es schon einen Sieger gibt. Falls ja wird eine Meldung ausgegeben mit dem Gewinner und die Spalten-Buttons verschwinden, damit keine neuen Steine gesetzt werden können.

Damit die Spielsteine in die Spalte fallen, haben wir den Spielstein-Objekten ein "Rigidbody" verpasst. Dem Rigidbody können dann "Gravity"-Werte gegeben werden, wodurch die Steine fallen.

Der potentielle Gewinner wird wie schon erwähnt ermittelt, nachdem einer der Spalten-Buttons geklickt wurde.
Dazu muss erwähnt werden, dass jedes Mal wenn ein neuer Stein gesetzt wird, ein Feld in einem Array entweder mit 0 oder 1 ausgefüllt wird, 0 und 1 stehen für die beiden Spieler.
Zur Überprüfung wird mit mehreren komplexen Algorithmen das Array untersucht und kontrolliert, ob vier gleiche Werte (0 oder 1) in einer Reihe vertikal, horizontal oder diagonal sind.

Endprodukt

Um die Anwendung ausführen zu können braucht es grundsätzlich keine Installation, es gibt lediglich eine .exe-Datei und einen Ordner mit Unity-Dateien, die sich beide am selben Ort befinden müssen.
Wenn man die .exe-Datei ausführt, erscheint zuerst eine Unity-Startanimation (da wir die kostenlose Unity-Version benutzen).
Danach wird man zum Start-Screen weitergeleitet. Dieser sieht folgendermassen aus:



Der Start-Screen beinhaltet im Wesentlichen zwei Buttons: Den Play-Button, um das Spiel zu starten und den Close-Button, der die Applikation schliesst.
Unten links sieht man ein Lautsprecher-Symbol, welcher dafür gedacht gewesen wäre, den Ton der Anwendung ein- und auszuschalten. Da es aber nun keinen Ton gibt, bewirkt dieser Button nichts.
Hat man den Play-Button betätigt, kommt man zum Spiel-Screen:



Der Spiel-Screen verfügt rechts über die beiden Buttons "Restart" und "Exit". Letzterer beendet auch hier wieder die ganze Applikation. Mit dem Restart-Button kommt man wieder zum Start-Screen, wo man über "Play" das Spiel neu starten kann.
Unter den sechs Spalten befinden sich die Spalten-Buttons. Die werden wie schon erwähnt verwendet, um einen Spielstein in die gewünschte Spalte fallen zu lassen.

Das folgende Bild zeigt, wie es aussieht, wenn man einen der Spalten Buttons klickt.




Wie man sieht, werden abwechslungsweise rote bzw. gelbe Steine gesetzt.
Hat einer der Spieler vier  Steine der gleichen Farbe in einer Reihe (vertikal/horizontal/diagonal) gewinnt er das Spiel:






Momentaner Stand

Zum Zeitpunkt, an dem dieser Blogeintrag verfasst wurde, ist das Projekt noch nicht ganz abgeschlossen, die Programmierarbeiten sollten jedoch fertig sein. Wenn es dennoch Probleme oder Fehler geben sollte, würden diese noch korrigiert werden.
Zum Abschluss werden wir in der Schule eine Präsentation über das Endprodukt halten müssen.
Man wird anschliessend eine Gesamtnote für das ganze Projekt erhalten und keine Modulabschlussprüfung mehr schreiben.

Keine Kommentare:

Kommentar veröffentlichen