Muehle

Aus toolbox_interaktion
Wechseln zu: Navigation, Suche
Design des Mühlefeldes

Mühle - Die Idee

In diesem Projekt ging es darum, ein Mühle Spiel zu erstellen.

Das Mühle Spiel wird an die Wand projiziert. Man braucht zum Spiele nur einen farbigen Handschuh, denn mit diesen kann man die Steine bewegen.

Umsetzung

OpenFrameworks

Wir haben uns für OpenFrameworks in Visual Studio entschieden und konnten uns anhand eines Beispiels des Farbtrackings orientieren. Die Addons, die in unserem Code laufen: ofxCv, ofxOpenCv, ofxGui.

Es gab während des Programmierens ein paar Probleme, wie z.B. dass man fälschlicherweise Steine aufgenommen hat, wenn man sich mit einem Stein über andere bewegt hat, aber das lies sich am Ende doch noch gut klären. Spiegeln des Bildschirm haben wir mit dem Xubuntu Betrieb-System gelöst. Wir haben in den Einstellungen nur den Bildschirm spiegelverkehrt übertragen lassen. So sind die Bewegungen rechts und links vor der Kamera nicht verkehrt herum.

Das Design

Zuerst wollten wir einfach ein Schwarz-Weises Mühlefeld nutzen, aber dann hat man die schwarzen Steine schlecht gesehen, weshalb wir uns dann doch für die schönere Holzoptik entschieden haben.

Das Brett entstand aus einer Holzfotografie von Wikimedia und einem selbst erstellten Overlay des Spielfeldes.

   600px-Muehle bill quadrat.jpg

Die Spielsteine haben wir auch in Photoshop erstellt.

   Spielstein Black gross.pngSpielstein White gross.png


Aufbau

Das Spielfeld und das Kamerabild wird mit einem Projektor an eine Wand projiziert. Die Kamera steht an der Wand in Blickrichtung zu den Spielern selbst und kann so den farbigen Handschuh tracken.

   Muehle Schemga-neu.png

Screenshot vom fertigen Spiel (allerdings ohne Projektor):

   Spiel Screenshot.png

Das Spiel und der Code

Am Anfang des Spiels sind alle Steine erst rechts an der Seite. Farb-Werte vom Handschuh sind im Code schon eingetragen, aber falls die Farbe wegen Lichtverhältnisse nicht erkannt wird, kann man auf dem Bild mit dem Cursor auf den Handschuh klicken, sodass neue Farbwerte übernommen werden.

Solange der Handschuh im Blickfeld des Kamera ist, wird er getrackt. Auf dem Spielfeld wird ein roter Punkt durch Tracking bewegt.

Steine Bewegen

Steine können bewegt werden, wenn man mit dem roten Punkt(Spiel Cursor) ca. 2 Sekunde auf einem Stein stehenbleibt. Der Stein wird aufgenommen, und kann dann auf dem ganzen Spielfeld bewegt werden. Wenn der Stein in der Nähe von einem schwarzen Punkt ist (ca. 10px), fängt der Counter an zu zählen. Wenn man auf dem Punkt ca. 2 Sekunden ununterbrochen stehengeblieben ist, dann wird der Stein auf dem Spielfeld bzw. auf dem schwarzen Punkt gesetzt. Das wird solange weiter gemacht bis alle Steine auf dem Spielfeld sind. Gegen Ende des Spiel müssen die Steine von Gegner abgenommen werden, die Phase funktioniert auch genauso wie bei Steine Wegnehmen, Bewegen und Setzen.

Steine auf den Punkten Anheften

Eine schwierigen Aufgaben war es, für die Steine einen Platz zu vergeben, damit die Steine nicht überall auf den Spielplatz gesetzt werden können, z.B. wenn man den Stein genommen hat, und etwas überlegen muss, wohin mit dem Stein setzt ... hätte man ohne diese Lösung den Stein nach ca. 2 Sekunde "aus der Hand fallen lassen". Mit unteren Code Abschnitt werden für jeden Punkt x und y Koordinaten vergeben.


   static float placeCoordinates[] = {640, 0, 865, 0, 1090, 0,
                                      715, 70, 865, 70, 1015, 70,
                                      790, 140 ,865, 140, 940, 140,
                                      640, 215, 715, 215, 790, 215, 940, 215, 1015, 215, 1090, 215,
                                      790, 290 ,865, 290, 940, 290,
                                      715, 360, 865, 360, 1015, 360,
                                      640, 430, 865, 430, 1090, 430,
                                      1150, 0};

Hier entsteht für jeden Punkt ein Kästchen, wo in dem Gameloop mit "if" abgefragt wird, ob sich ein Stein darin befindet.

    if(
              ((centroid.x + width) > placeCoordinates[i]) &&
              ((centroid.x + width) < (placeCoordinates[i] + 40)) &&
              (centroid.y > placeCoordinates[i+1]) &&
              (centroid.y < (placeCoordinates[i+1] + 40))
              )

Kollisionen Vermeiden

"Wenn ein Stein bewegt wird und mit dem Stein über einen anderen Stein gegangen wird, werden die Steine getauscht. Wenn wir den weißen Stein haben und über einen schwarzen gehen, dann haben wir nach der Kollision den schwarzen Stein."

Das war auch ein Problem, das wir lösen mussten. Dafür sollte man alle Counter(zum Warten bevor ein Steine genommen wurde) von den Steinen auf "null" setzen, außer für den Stein, den wir in der Hand haben. Das haben wir mit dem unteren Codeabschnitt gelöst.


           // Steine Kolisionvermeindung
           for (int i = arr2 + 1; i <= 18; i++) {
               stoneTake[i] = 0;
           }
           if (arr2 > 0) {
               for (int i = arr2 - 1; i >= 0; i--) {
                   stoneTake[i] = 0;
               }
           }
           // Steine Kolisionvermeindung Ende

Zukunftsausblick

Zunächst könnte man auch noch Spielregeln mit einbauen, z. B. das man wenn man nur noch 3 Steine zur Verfügung hat "springen" darf und sonst nicht.

Da wir es vorerst so gelöst hatten, dass wir den Bildschirm spiegel, könnte man in Zukunft sicher auch eine Lösung dafür finden, dass es direkt im Spiel gespiegelt wird.

Links

Holz-Hintergrundbild: Nussbaum Holz

Quellcode