Projektarbeit Entwicklung des Computerspiels „Vier Gewinnt“ mit Java 3D Prüfungsfach Systemprogrammierung WS 2003/2004 Vorgelegt bei Prof. Dr. S. Groß Prof. Dr. W. Heinzel Fachhochschule Fulda Fachbereich Angewandte Informatik Mitglieder der Projektgruppe: Raymund Witzel André Och Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Inhaltsverzeichnis -1- Inhaltsverzeichnis 1. Benutzerdokumentation ........................................................................................ 4 1.1. Einzelspiel-Modus ......................................................................................... 4 1.1.1. Neues Spiel starten .................................................................................. 5 1.1.2. Ball setzen ................................................................................................ 5 1.1.3. Spielende ................................................................................................. 6 1.2. Netzwerkspiel-Modus.................................................................................... 6 1.2.1. Spielen als Server .................................................................................... 6 1.2.2. Spielen als Client ...................................................................................... 7 1.2.3. Neues Spiel im Netzwerk starten.............................................................. 7 1.2.4. Netzwerkspiel abbrechen ......................................................................... 7 1.3. Ton und Geräusch an-/ausschalten .............................................................. 8 1.4. Programminformationen anzeigen ................................................................ 8 1.5. Drehen des Spielbretts ................................................................................. 8 1.6. Programm beenden ...................................................................................... 8 2. Aufgabenstellung und Vorstellung des Projektthemas ...................................... 8 2.1. Definition der Projektziele ............................................................................. 8 2.2. Verwendete Mittel ......................................................................................... 10 3. Verteilung der Aufgaben auf die Projektmitglieder ............................................. 10 4. Festlegung der wichtigsten Schnittstellen zwischen den Klassen der Projektmitglieder ................................................................................................... 11 5. Realisierung der Spielsteuerung .......................................................................... 13 5.1. Vorbereitung eines neuen Spieles ................................................................ 14 5.2. Registrierung und Anzeigen der gesetzten Bälle .......................................... 14 5.3. Ermittlung des Gewinners ............................................................................. 16 5.3.1. Überprüfung der Zeile des aktuellen Feldes ............................................. 16 5.3.2. Überprüfung der Spalte des aktuellen Feldes .......................................... 16 5.3.3. Überprüfung der Diagonalen von links unten nach rechts oben ............... 17 5.3.4. Überprüfung der Diagonalen von rechts unten nach links oben ............... 17 5.4. Ermittlung und Anzeigen der Siegerbälle ...................................................... 18 5.5. Modus Einzel-/Netzwerkspiel ........................................................................ 19 5.5.1. Neues Netzwerkspiel beginnen ................................................................ 19 5.5.2. Neues Einzelspiel beginnen ..................................................................... 20 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Inhaltsverzeichnis -2- 5.5.3. Bälle im Netzwerkspiel setzen .................................................................. 21 5.5.4. Bälle im Einzelspiel setzen ....................................................................... 22 5.5.5. Netzwerkspiel abbrechen ......................................................................... 22 5.6. Beschreibung sonstiger Methoden der Spielsteuerung................................. 22 5.6.1. Zugriff auf die Statustextzeile ................................................................... 22 5.6.2. Zugriff auf die Menüoptionen .................................................................... 23 5.6.3. Ausschaltung der Musik und Geräusche .................................................. 23 6. Implementierung des Servers ............................................................................... 23 6.1. Erstellung des Servers .................................................................................. 23 6.2. Aufgaben des Servers .................................................................................. 24 6.2.1. Annahme von Verbindungen .................................................................... 24 6.2.2. Nachrichtenaustausch .............................................................................. 24 6.3. Beenden des Servers ................................................................................... 26 7. Einsatz von Musik und Geräuschen ..................................................................... 27 7.1.1. Auswahl der Audiodaten........................................................................... 27 7.1.2. Bearbeitung der Audiodaten ..................................................................... 28 7.1.3. Beschreibung der Klasse Musikspieler ............................................... 28 8. Zweidimensionale Fensterelemente (Graf. Oberfläche) ..................................... 29 8.1. Das Hauptfenster .......................................................................................... 29 8.2. Das Fenstermenü ......................................................................................... 30 8.3. Der Fensterinhalt .......................................................................................... 32 8.3.1. Die Panels ................................................................................................ 32 8.3.2. Die Ansteuerung der Stäbe ...................................................................... 33 8.3.3. Statusmeldungen...................................................................................... 34 8.3.4. Erläuterung der Klasse BildKomponente .................................................. 34 9. Dreidimensionale Spielszene (Graf. Oberfläche) ................................................ 35 9.1. Allgemeine Grundlagen ................................................................................ 35 9.2. Aufbau des Szenengraphen ......................................................................... 38 9.3. Gestaltung der Ansicht.................................................................................. 39 9.4. Festlegen der Belichtung .............................................................................. 40 9.4.1. Ambientes Licht ........................................................................................ 40 9.4.2. Direktionales Licht .................................................................................... 41 9.4.3. Der Hintergrund ........................................................................................ 42 9.5. Aufbau des Spielbretts .................................................................................. 42 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Inhaltsverzeichnis -3- 9.5.1. Die Einzelbretter ....................................................................................... 42 9.5.2. Die Spielstäbe .......................................................................................... 45 9.6. Erzeugung und Kontrolle der Bälle ............................................................... 46 9.6.1. Ballerzeugung .......................................................................................... 47 9.6.2. Ballkontrolle .............................................................................................. 49 10. Implementierung des Clients ................................................................................ 50 10.1. Erstellung des Clients ................................................................................... 50 10.2. Aufgaben des Clients .................................................................................... 50 10.2.1. Initiierung des Verbindungsaufbaus ......................................................... 50 10.2.2. Nachrichtenaustausch .............................................................................. 51 10.3. Beenden des Clients ..................................................................................... 52 11. Auslagerung der Einstellungen ............................................................................ 52 12. Installation und Ausführung des Programms ..................................................... 52 12.1. Installation und Ausführen unter Windows .................................................... 53 12.2. Installation und Ausführen unter Linux SuSE ................................................ 53 12.3. Ausführen in den Rechnerräumen C002 bis C005 in der Fachhochschule Fulda ............................................................................................................. 53 13. Anhang.................................................................................................................... 54 13.1. Abbildungsverzeichnis .................................................................................. 54 13.2. Inhalt der Projekt CD..................................................................................... 54 13.3. Quellenverzeichnis........................................................................................ 55 14. Anlagen ................................................................................................................... 58 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Vorwort und Benutzerdokumentation -4- Vorwort Diese Dokumentation wurde im Rahmen der Prüfungsleistung „Systemprogrammierung“ erstellt. Sie setzt sich aus zwei größeren Teilabschnitten zusammen, die von den Projektmitgliedern selbstständig bearbeitet wurden. Um die Übersichtlichkeit der Dokumentation zu verbessern, wurden die beiden Teile als zwei Blöcke, wie in den Richtlinien durch die Prüfer festgelegt, von uns zu einem Dokument zusammengefügt. Dieses ist auf der Doku_VierGewinnt.doc Projekt-CD im Verzeichnis CD-Laufwerk:\Dokumentation\ zu finden. Die Dokumentation liegt dort auch als pdf-Dokument vor. Im Zuge der Projektarbeit wurde auf fremde Quellen zurückgegriffen. Um die betreffenden Stellen in dieser Dokumentation eindeutig zu kennzeichnen, wurde am Ende eines betreffenden Absatzes ein Verweis in Form von [Q X] angebracht, wobei X deren Nummerierung darstellt. Die Auflistung der einzelnen Quellen ist im beiliegenden Anhang aufgeführt (siehe Punkt 13.3 „Quellenverzeichnis“). Zum besseren Verständnis der nachfolgenden Dokumentation, verweisen wir schon jetzt auf die Anlage 1 „Klassendiagramm“, die Anlage 2 „Java3D-Szenengraph“ und die Anlage 3 „Quellcode zum Programm „Vier Gewinnt“ hin. 1. Benutzerdokumentation In diesem Abschnitt wird dem Benutzer die Bedienung und Handhabung des Computerspiels „Vier Gewinnt“ nahe gebracht. Es wird hier ausschließlich das Programm im laufenden Betrieb beschrieben. Auf die Installation und das Starten des Programms wird im Punkt 12 „Installation und Ausführung des Programms“ näher eingegangen. 1.1. Einzelspiel-Modus Beim Start des Computerspieles „Vier Gewinnt“ befindet sich das Programm im Einzelspiel-Modus, d. h. dass beide Spieler das Programm gleichzeitig auf einem Rechner bedienen (siehe auch Punkt 2.1 „Definition der Projektziele“). Die folgende Abbildung 1 zeigt die grafische Oberfläche zur Bedienung des Programms nach dem Programmstart. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Benutzerdokumentation -5- Abbildung 1: Programmmenü des Computerspiels "Vier Gewinnt" Wie aus dem Schaubild zu entnehmen ist, hat der Hauptmenübereich „Spiel“ insgesamt fünf Unterpunkte, auf die nachfolgend näher eingegangen wird. 1.1.1. Neues Spiel starten Um ein Spiel im Einzelspiel-Modus zu starten, ist der Untermenüpunkt Neues Spiel starten aufzurufen. Im oberen Bereich des Spielfensters wird nun der erste Spieler durch Anzeigen einer Statusmeldung aufgefordert, das Spiel zu beginnen, d. h. es darf der erste Ball gesetzt werden. Im Einzelspiel hat der erste Spieler stets die roten Bälle, sein Gegenspieler immer die gelben. 1.1.2. Ball setzen Die sieben Spielstäbe des Spielbretts sind dafür vorgesehen, die roten und gelben Bälle beider Spieler aufzunehmen. Diese werden im Wechsel gesetzt. Unterhalb eines jeden Stabes sind „Buttons“ angebracht, die mit den Ziffern 1 bis 7 belegt wurden. Abbildung 2: Setzen des Balles Damit ein Spieler einen Ball auf einen bestimmten Stab setzen kann, muss er mit der Maus auf den darunter liegenden „Button“ drücken. Nach jedem Spielzug wird in der Statuszeile der nächste Spieler zum Zug aufgefordert: Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Benutzerdokumentation -6- Abbildung 3: Meldung in der Statuszeile 1.1.3. Spielende Jeder Spielstab kann sechs Spielbälle in seiner Höhe aufnehmen. Sinn des Spieles ist es, im Wettstreit zu seinem Gegenspieler, vier eigene direkt an einander liegende Bälle in horizontaler, vertikaler oder diagonaler Richtung zu setzen. Der Spieler, dem dieses zuerst gelingt, ist der Sieger. Die Siegerbälle leuchten auf, und das Spiel ist damit beendet. Abbildung 4: Spielende durch Sieg Das Spiel ist ebenfalls beendet, wenn alle Bälle gesetzt wurden und keiner der Spieler gewonnen hat. Das Spiel kann auch vorzeitig durch Aufruf des Untermenüpunktes Neues Spiel starten beendet und damit neu begonnen werden. 1.2. Netzwerkspiel-Modus Ebenfalls kann das Spiel im Netzwerkspielmodus ausgeführt werden. Dies bedeutet, das zwei Spieler auf verschiedenen Rechnern über ein Netzwerk verteilt spielen können (siehe auch Punkt 2.1 „Definition der Projektziele“). Hierbei haben der Server immer die roten und der Client immer die gelben Bälle. 1.2.1. Spielen als Server Im Netzwerkspiel-Modus übernimmt der Server-Rechner die Rolle des Koordinators. Nur dieser kann ein Netzwerkspiel beginnen und bestimmt, welcher Spieler den ersten Zug macht. Am Anfang des Netzwerkspieles muss zuerst der Server erstellt werden. Dazu betätigt der Spieler am Server den Untermenüpunkt Neues Spiel im Netzwerk eröffnen. Der Server wartet nun auf die Spielanfrage des Clients. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Benutzerdokumentation 1.2.2. -7- Spielen als Client Nachdem ein Server im Netzwerk existiert, muss der Spieler am Client-Rechner den Untermenüpunkt Am Spiel im Netzwerk teilnehmen betätigen. Daraufhin erscheint folgendes Dialogfenster: Abbildung 5: IP-Adresse des Servers angeben Der Spieler kann nun die IP-Adresse oder auch den Hostnamen des ServerRechners eingegeben. Nach erfolgreichem Verbindungsaufbau erscheint in der Statuszeile die Meldung, dass mit dem Server der eingegebenen Adresse ein Verbindung eingegangen wurde. 1.2.3. Neues Spiel im Netzwerk starten Analog zum Client erhält der Server eine Meldung bzgl. des Verbindungsaufbaus. Es obliegt nun ausschließlich dem Server, den Untermenüpunkt Neues Spiel starten auszuführen, durch den folgender Dialog am Bildschirm erscheint: Abbildung 6: Auswahl des Spielbeginners Der Spieler am Server-Rechner entscheidet nun, wer den ersten Zug macht. Der weitere Spielverlauf entspricht dem im Einzelspiel-Modus. 1.2.4. Netzwerkspiel abbrechen Ein Netzwerkspiel kann von beiden Parteien durch den Untermenüpunkt Aktuelles Netzwerkspiel beenden vorzeitig abgebrochen werden. Hinweis: Dieser Untermenüpunkt steht selbstverständlich nur während eines Netzwerkspieles zur Verfügung und ist ansonsten analog der Abbildung 1 „ausgegraut“. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Benutzerdokumentation und Projektbeschreibung -8- 1.3. Ton und Geräusch an-/ausschalten Wenn das Programm standardmäßig mit Musik- und Tonunterstützung gestartet wurde (diese kann deaktiviert werden, wenn das Programm mit dem Parameter –musikAus aus der Konsole gestartet wird), steht der Untermenüpunkt Ton aus/Ton ein zur Verfügung. Über diesen lässt sich die Ton-Wiedergabe im Programm unterbinden und wieder einschalten. 1.4. Programminformationen anzeigen Im Menübereich Info besteht die Möglichkeit, durch Auswahl des Menüunterpunktes Team sich Informationen zu diesem Projekt anzeigen zu lassen. 1.5. Drehen des Spielbretts Mit der linken gedrückten Maustaste kann das Spielbrett in der 3D-Grafikszene in eine beliebige Position gedreht werden. 1.6. Programm beenden Das Programm kann zu jeder Zeit beendet werden, indem das Spielfenster geschlossen oder der Untermenüpunkt Beenden des Menübereichs Datei ausgewählt wird. 2. Aufgabenstellung und Vorstellung des Projektthemas Es soll ein interaktives Computerspiel entwickelt werden, dass sich an die Regeln des oben vorgestellten Spieles „Vier Gewinnt“ anlehnt. 2.1. Definition der Projektziele Die Projektmitglieder setzen sich folgende Ziele zur Pflicht: Einerseits soll das Computerspiel an einem einzelnen Computer spielbar sein. Hierbei bedienen beide Gegenspieler den gleichen Rechner. Dieser Spielmodus wird von uns künftig als Einzelspiel bezeichnet. Andererseits soll ein verteiltes Spielen zwischen zwei Rechnern über ein Netzwerk ermöglicht werden. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung -9- Hierzu übernimmt ein Computer die Rolle des Servers, der einen teilnehmenden Client in das Netzwerkspiel aufnimmt, dieses initiiert und steuert. Der Client muss zur Verbindungsaufnahme die entsprechende IP-Adresse oder den Rechnernamen des zuvor erstellten Servers angeben. Es ist anzumerken, dass sowohl auf dem Rechner des Clients als auch auf dem des Servers das gleiche Programm läuft, d. h. dieses integriert gleichzeitig beide Programmteile für die Kommunikation. Diese erfolgt zwischen den beiden Rechnern über eine TCP-Verbindung. Es erfolgt dabei eine wechselseitige Kommunikation der Spielrechner, das bedeutet, dass der aktuell gesetzte Ball simultan auf dem eigenen sowie auf dem entfernten Rechner angezeigt wird. Hat einer der Spieler gewonnen, so muss dieses Ereignis beiden Teilnehmern erkennbar sein, was eine Hervorhebung der Siegerbälle einbezieht. Etwaige Fehlbedienungen werden nur dem Benutzer, der den Fehler verursachte, angezeigt. Ferner erhält jeder Computer die Möglichkeit, das aktuelle Netzwerkspiel zu beenden; eine entsprechende Mitteilung muss dabei an den entfernten Teilnehmer erfolgen. Die komplette Bedienung des Programms soll über die Maus erfolgen. Um einen Ball zu setzen, sind hierfür entsprechende „Buttons“ zu betätigen. Zur Auswahl von Spieloptionen ist eine Programmmenüleiste vorgesehen. Über diese können Einzeloder Netzwerkspiele gestartet oder beendet werden. Das Computerspiel soll auf Unix- als auch auf Windows-Betriebssystemen lauffähig sein. Die Darstellung des Spielbretts einschließlich seiner Bälle hat dreidimensional zu erfolgen. Zusätzliche Erweiterungsziele sind für das Projekt vorgesehen: Um für weiteren Spielspass zu sorgen, ist der Einsatz von musikalischer Untermalung eingeplant. Außerdem kann eine Animation des Spielers durch eine entsprechende Geräuschkulisse während des Spiels erhöht werden. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 10 - 2.2. Verwendete Mittel Zur Realisierung des Programms werden nur die von Sun Microsystems definierten Sprachmittel Java sowie die Java 3D API verwendet. Die grafische Oberfläche des Programms wird einerseits mit Hilfe der Fensterklassen aus den „Packages“ awt und swing erstellt, andererseits wird für die Umsetzung des Spielbrettes sowie der Bälle die o. g. Programmierschnittstelle eingesetzt. Als Netzwerk-Transportprotokoll wird das TCP/IP Protokoll herangezogen. 3. Verteilung der Aufgaben auf die Projektmitglieder Im Antrag zu dieser Prüfungsleistung wurden bereits die Teilaufgaben für die Projektmitglieder entwurfartig festgelegt. Dieser Abschnitt geht in dessen Bezug auf diese Aufgabenbereiche detaillierter ein. Dem Projektmitglied André Och wurden die folgenden Aufgaben zugeteilt: Implementierung des Client-Teils: Diese Aufgabe umfasst die Klassen für die Kommunikation mit dem Server. Implementierung der Grafischen Oberfläche: Die grafische Oberfläche hat einerseits die Aufgabe, alle Ereignisse, die durch den Benutzer ausgelöst werden, entgegenzunehmen und diese entsprechend an die Spielsteuerung weiterzuleiten. Andererseits ist die grafische Oberfläche für die Darstellung der Resultate der Spielsteuerung verantwortlich (z. B. das Anzeigen der Bälle mittels Java 3D). Dem Projektmitglied Raymund Witzel wurden die folgenden Aufgaben zugeteilt. Implementierung des Server-Teils: Diese Aufgabe umfasst die Klassen für die Kommunikation mit dem Client. Implementierung der Spielsteuerung: Die Spielsteuerung nimmt die Eingaben der grafischen Oberfläche entgegen und wertet diese entsprechend aus. Sie ist für die Einhaltung der Spielregeln verantwortlich und regelt die Kommunikation zwischen Client und Server im Netzwerkbetrieb, d. h sie übernimmt zum Teil die Rolle der Nachrichtenauswertung. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 11 - 4. Festlegung der wichtigsten Schnittstellen zwischen den Klassen der Projektmitglieder Um die Programmierbereiche für die einzelnen Projektmitglieder exakt abzugrenzen, wurden vor der Implementierung geeignete Schnittstellen zwischen den einzelnen Hauptklassen festgelegt. Das im Projektantrag in der Anlage 2 mitgelieferte Schaubild zur Interaktion der Programmklassen, wurde dementsprechend verfeinert: Bei einer genaueren Systemanalyse zu o. g. Projekt, wurde festgestellt, dass es sinnvoll ist, auf der Seite des Clients ebenfalls eine Spielsteuerung vorzusehen, die simultan zu der des Server arbeitet. Der Vorteil dieser Implementierung liegt in dem erheblich geringeren Austausch der Nachrichten über das Netzwerk. Es muss lediglich der Index des Stabes, in welchem der aktuelle Ball gesetzt wurde, versendet werden. Spielstand, gesetzte Siegerbälle, Informationen über den Sieger u. s. w. ermittelt der Client selbst. Somit ergibt sich folgendes Schaubild der Schnittstellen: Abbildung 7: Grobes Schaubild der Schnittstellen Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 12 - Nachfolgend werden oben dargestellte Schnittstellen näher erörtert: beendeSpiel (): Wird von dem Spieler des Client- bzw. Serverrechners ausgelöst, um ein bestehendes Netzwerkspiel abzubrechen. registriereBallUndZeigeAn (int iStab): Diese Methode wird bereitgestellt, um einen Ball zu setzen, d. h. es erfolgt eine Registrierung bei der Spielsteuerung. Als Parameter dient der Index des Stabes, auf den der Ball gesetzt wird (0 <= iStab <= 6). ballVonEntferntenRechnerGesetzt (int iStab): Diese Methode wird aus den Kommunikationsklassen aufgerufen, wenn auf dem entfernten Rechner ein Ball gesetzt wird. setzeBallBeiServer (int iStab): Diese Methode wird vom Client-Rechner aufgerufen, um dem Server mitzuteilen, auf welchen Stab iStab gerade der Ball gesetzt wurde. setzeBallBeiClient (int iStab): Diese Methode wird vom Server-Rechner aufgerufen, um dem Client mitzuteilen, auf welchen Stab iStab gerade der Ball gesetzt wurde. setzeBall (int iPos): Der Aufruf dieser Methode erfolgt in der Spielsteuerung und wird vorgenommen, wenn ein Ball auf einer entsprechenden Position iPos grafisch angezeigt werden soll (wobei 0 <= iPos <= 41). Im Zuge der Projektarbeiten musste jedoch festgestellt werden, dass o. g. Schnittstellen nicht ausreichten. Es mussten zusätzliche Schnittstellen vereinbart werden, die von den jeweiligen Projektmitgliedern zu einem späteren Zeitpunkt erläutert werden. Das Grobkonzept beinhaltet z. B. noch nicht die Möglichkeit, neue Spiele (Einzelspiele oder Netzwerkspiele) zu starten oder Siegerbälle anzuzeigen. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 13 - 5. Realisierung der Spielsteuerung Die Spielsteuerung des Computerspieles „Vier Gewinnt“ ist in der Programmklasse Spielsteuerung, welche sich in der Datei „Spielsteuerung.java“ befindet, implementiert. Sie ist das Bindeglied zwischen der Benutzereingabe und der Darstellung auf der grafischen Oberfläche, d. h. Eingaben werden entgegengenommen, ausgewertet und das Resultat zur Anzeige an die grafische Oberfläche zurückgegeben. Zur Verwaltung des Spieles wird das zweidimensionale Array arSpielfeld [][] verwendet, welches im folgenden Schaubild visualisiert wird: Abbildung 8: Darstellung des Arrays für die Aufnahme der Bälle Das Vorhandensein bzw. das Nichtvorhandensein eines Balles wird in dem oben dargestellten Array gespeichert. Felder ohne Ball besitzen den Wert 0. Wird ein Ball gesetzt, so erhält das entsprechende Spielfeld, den Standartwert des Spielers. Der Standardwert des Spielers hängt von der Farbe seiner Spielbälle ab. Rot hat immer den Wert 1, Gelb hat immer den Wert 2. Um ein einzelnes Spielfeld im Spielbrett anzusprechen, erhält jedes Feld einen Zeilenindex z und einen Spaltenindex s. Zudem hat jedes Feld einen laufenden Index. Dieser wird von der grafischen Oberfläche für das Anzeigen der Bälle verwendet. Die Spielsteuerung umfasst u. a. die folgenden Aufgaben, die umseitig erläutert werden: Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 14 - 5.1. Vorbereitung eines neuen Spieles Um ein neues Spiel beginnen zu können, müssen die Felder des o. g. Arrays mit dem Wert 0 initialisiert werden. Hierzu wird die Methode neuesSpielStarten (int iBeginner) aufgerufen. Als Parameter wird der Spielbeginner übergeben. Die- ser wird als erster aktueller Spieler gesetzt, indem die globale Variable iAktSpieler den entsprechenden Standardwert zugewiesen wird. Bei einem Einzelspiel beginnt stets der Spieler Rot. Bei einem Netzwerkspiel bestimmt der Spieler am Server, wer das Spiel beginnt. Hierbei hat der Server immer den Standwert 1 (rote Bälle) und der Client immer den Standardwert 2 (gelbe Bälle). Falls zuvor ein Spiel durchgeführt wurde, müssen Siegerbälle mittels der Methode faerbeBallNeu () in ihren Ursprungszustand zurückgesetzt werden (siehe Punkt 5.4 „Ermittlung und Anzeigen der Siegerbälle“). Um eventuell gesetzte Bälle von der grafischen Oberfläche zu entfernen, wird die Methode setzeNeuesSpiel () der Klasse Ballkontrolle aufgerufen. Ebenfalls werden globale Variablen initialisiert, wie z. B. die Anzahl der gesamten gesetzten Bälle im Spiel iAnzGespielBaell. Des Weiteren wird dafür gesorgt, dass die Anfangsmusik, welche beim Programmstart oder nach einem gewonnen Spiel ertönt, abgeschaltet wird, um die anschließenden Spielgeräusche nicht zu überlagern. Hiezu werden die Methoden der Klasse Musikspieler aufgerufen (siehe Punkt 5.6 „Beschreibung sonstiger Methoden der Spielsteuerung“). 5.2. Registrierung und Anzeigen der gesetzten Bälle Die Methode registriereBallUndZeigeAn (int iStab) ist für die Registrierung der gesetzten Bälle in dem bereits beschriebenen Array arSpielfeld verantwortlich. Dazu wird die Methode setzeWertInArray (iStab) aufgerufen. Diese sucht in der vom Spieler ausgewählten Spalte mit dem Index iStab das „unterste leere“ Spielfeld (mit Standardwert 0) und setzt hier den Standartwert des aktuellen Spielers (1 oder 2). Rückgabewert ist der Zeilenindex z des aktuellen Feldes. Ist die ausgewählte Spalte bereits mit Standardwerten von Spieler komplett aufgefüllt, kann kein Eintrag in dem Array stattfinden. Die Methode istSpalteVoll (int z, int s) gibt dann einen true-Wert zurück. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung Das Anzeigen der gesetzten (int iSpieler, int iPosition) Bälle wird - 15 - über die Methode setzeBall der Klasse Ballkontrolle ermöglicht. Diese ver- langt als Parameter den aktuellen Spieler iAktSpieler (globale Variable) und den laufenden Index des aktuellen Feldes als Position. Der benötigte laufende Index wird mit Hilfe der Methode gibLaufenderIndex (int z, int s) ermittelt. Diese verwendet dazu folgende Formel: Laufender Index iIndex = akt. Zeile z + akt. Spalte s + (ASpalten – 1) x akt. Zeile z Die Ermittlung des Index wird an folgendem Beispiel verdeutlicht: akt. Zeile z = 1 akt. Spalte s = 3 ASpalten = 7 (entspricht der globalen Konstante ANZAHL_SPALTEN) Abbildung 9: Ermittlung des laufenden Index Laufender Index iIndex = 1 + 3 + (7 – 1) x 1 = 10 Nachdem der Ball grafisch dargestellt wird, erfolgt die Überprüfung, ob der aktuelle Spieler iAktSpieler das Spiel gewonnen hat. Hierzu wird die Methode ueberpruefeObGewonnen (int z, int s) aufgerufen (siehe 5.3 „Ermittlung des Ge- winners“). Konnte kein Sieger für das aktuelle Spiel ermittelt werden, so wird der Gegenspieler zum aktuellen Spieler. Wenn das Programm mit Musik- und Tonunterstützung gestartet wurde (dies kann über den globalen Parameter bProgMitMusik ermittelt werden), wird die Methode spieleSoundSetzeBall () Bearbeitet von: Raymund Witzel der Klasse Musikspieler aufgerufen. Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 16 - 5.3. Ermittlung des Gewinners Die Methode ueberpruefeObGewonnen (int z, int s) stellt wie bereits erwähnt fest, ob der aktuelle Spieler mit dem aktuellen Ball (Spielzug) das Spiel gewonnen hat. Der implementierte Algorithmus arbeitet nach folgender Vorgehensweise: 5.3.1. Überprüfung der Zeile des aktuellen Feldes Es wird die aktuelle Zeile mit dem übergebenen Zeilenindex z beginnend mit dem kleinsten Spaltenindex bis zum Feld mit dem größten Spaltenindex überprüft. Gehört der Eintrag eines überprüften Feldes dem aktuellen Spieler, so wird die Zählvariable iAnz um eins erhöht. Mit Hilfe der Klasse Siegerball wird die Position (dies ist der Spalten- und Zeilenindex des gerade geprüften Feldes) sowie die Zählvariable iAnz und der Standardwert des aktuellen Spielers zwischenzeitlich abgespeichert. Der Sieger ist festgestellt, falls die Variable iAnz den Wert 4 annimmt. Die Methode gibt dann den Wert true zurück. Gehört in dem anderen Falle der Eintrag des überprüfenden Feldes nicht zu dem aktuellen Spieler, so wird die Zählvariable iAnz zurückgesetzt und die zwischengespeicherten Siegerbälle der Klasse Siegerball werden gelöscht. Die genaue Funktionsweise der Klasse Siegerball wird in dem Punkt 5.4 „Ermittlung und Anzeigen der Siegerbälle“ beschrieben. 5.3.2. Überprüfung der Spalte des aktuellen Feldes Es wird die aktuelle Spalte mit dem übergebenen Spaltenindex s, beginnend mit dem kleinsten Zeilenindex bis zum Feld mit dem größten Zeilenindex solange überprüft, bis entweder ein Sieger nach oben beschriebenen Vorgang festgestellt wurde oder aber ein Feld vorliegt, dass den Standardwert 0 beinhaltet. Oberhalb eines leeren Spielfeldes kann sich kein Ball befinden. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 5.3.3. - 17 - Überprüfung der Diagonalen von links unten nach rechts oben Es ist zuerst das Spielfeld mit dem kleinsten Index der Spalte sowie dem kleinsten Index der Zeile der aktuellen Diagonale zu ermitteln. Beide Indizes werden vom aktuellen Spielfeld jeweils stets um eins heruntergezählt, bis gerade noch einer oder beide Indizes sich im Bereich des Spielbrett-Arrays befinden. Das Feld mit den gefundenen „Mindest-Indizes“ ist in der aktuellen Diagonale das „unterste“ Feld. Als nächstes ist das Spielfeld mit den größten Indizes der Diagonale zu ermitteln. Beginnend mit dem „untersten“ Feld der Diagonalen wird jede Spielzelle überprüft. Das Überprüfen der Diagonale wird beim Erreichen des „obersten“ Feldes der Diagonale oder bei der Ermittlung eines Siegers (nach in Punkt 5.3.1 „Überprüfung der Zeile des aktuellen Feldes“) abgebrochen. Nachfolgend wird die Vorgehensweise bei der Prüfung der Diagonalen anschaulich dargestellt: Abbildung 10: Die diagonale Laufrichtung 5.3.4. Überprüfung der Diagonalen von rechts unten nach links oben Der Algorithmus entspricht dem unter Punkt 5.3.3 erläuterten Verfahren mit dem Unterschied, dass der Laufindex der Zeile aufsteigend und der Laufindex der Spalte fallend ist. Haben die unter Punkt 5.3.1 bis 5.3.4 beschrieben Algorithmen keinen Sieger ermittelt, so liefert die Methode ueberpruefeObGewonnen (int z, int s) ein false zurück. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 18 - 5.4. Ermittlung und Anzeigen der Siegerbälle Diese Klasse SiegerBall befindet sich in der Datei „Spielsteuerung.java“ und verwaltet die Siegerbälle sowie den letzen aktuellen Spieler der gewonnen hat. Hierzu führt sie das Array Ball, in welchem die Positionen (Spaltenindizes und Zeilenindizes) der Siegerbälle gespeichert sind. Zur Speicherung der Siegerbälle wird die Methode merkeSiegerBall (int z, int s, int iNr, int iSieg) aufgerufen. Es werden die jeweiligen Indizes z und s des gerade zu überprüfenden Feldes, der Index des Ball-Arrays sowie der Standardwert des möglichen Siegers (aktueller Spieler) übergeben. Der (int z, int s) Aufruf erfolgt in der Methode ueberpruefeObGewonnen in der Spielsteuerung, und zwar bei jedem zu überprüfenden Feld (siehe hierzu Punkt 5.3.1). Für das Anzeigen der Siegerbälle wird in der Methode registriereBallUndZeigeAn (int iStab) der Spielsteuerung die Methode gibLaufenderIndex (int k) aufgeru- fen. Es wird anhand der Spielfeldindizes z und s, die in dem Array Ball abgespeichert sind, der laufende Index des Spielfeldes, in dem sich der Siegerball k befindet, ermittelt. Die Spielsteuerung übergibt dann den ermittelten laufenden Index an die Methode setzeGewinnerBall (int iSpieler, int iPosition), um die Gewinnerbälle farblich hervorzuheben. Um auf den Punkt 5.1 „Vorbereitung eines neuen Spieles“ zurückzukommen, muss dafür gesorgt werden, dass bei einem neuen Spiel die Gewinner- bzw. Siegerbälle in ihren Ursprungszustand zurückgesetzt werden müssen. Hierzu sind in der Klasse SiegerBall (int iNr) die zwei Methoden gibDenSiegerAn () und gibPosSiegerBall implementiert. Diese liefern den Standardwert des letzten Siegers sowie die Positionen der vier Siegerbälle, die der Methode setzeGewinnerballRueck (int iSpieler, int iPosition) der Klasse Ballkontrolle einzeln übergeben wer- den, um das ursprüngliche Erscheinungsbild wieder herzustellen. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 19 - 5.5. Modus Einzel-/Netzwerkspiel Das Computerspiel unterstützt die beiden Betriebsmodi Einzel- und Netzwerkspiel. Im Einzelspielmodus wird das Spiel nur auf einem Rechner ausgeführt. Über den Rechner wird gleichzeitig der Spieler Rot (mit dem Standardwert 1) und der Spieler Gelb (mit dem Standardwert 2) bedient. Das Einzelspiel wird stets durch den Spieler Rot begonnen. Der Netzwerkspielmodus erlaubt das verteilte Spielen im Netzwerk. Das Programm hat sowohl den internen Server als auch den Client integriert, so dass zwei Spieler an zwei verschieden Rechnern frei entscheiden können, wer den Server ausübt. Es ist lediglich dem Spieler des Server-Rechners vorbehalten, zu bestimmen, wer das Spiel beginnt und wann das Spiel begonnen wird. 5.5.1. Neues Netzwerkspiel beginnen Server: Um das verteilte Spielen zu ermöglichen, muss zuerst ein Server erstellt werden. Dies erfolgt über die Methode erzeugeServer () der Spielsteuerung, dessen Aufruf aus der Klasse MenuErzeuger (diese gehört zur grafischen Oberfläche) erfolgt. In der Methode wird eine Instanz sServer der Klasse Server erzeugt, die es nun ermöglicht, dass sich ein Client verbinden kann (siehe Punkt 6.2.1 „Annahme von Verbindungen“). Des Weiteren wird die Methode setzeNeuesSpielMoeglich (boolean bSchalter) der Klasse MenuErzeuger aufgerufen, welche verhindert, dass der Server ein neues Spiel startet, so lange noch kein Client zu ihm verbunden hat. Client: Hat ein Spielgegner einen Server im vorliegenden Netzwerk erstellt, kann der Client-Rechner eine Verbindung zu diesem aufnehmen. Hierzu ist die Methode erzeugeClient (InetAddress addrServer) durch die Klasse MenuErzeuger aus- zulösen. Die übergebene Referenz addrServer, welche den Endpunkt des Server-Rechners beinhaltet, wird anschließend für die Erzeugung des Clients benötigt. Der Programmcode dazu lautet: cClient = new Client (addrServer, this). Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 20 - Nach erfolgreicher Instanziierung des Clients, versucht er eine Verbindung zu dem angegebenen Server herzustellen (siehe Punkt 10.2.1 „Initiierung des Verbindungsaufbaus“). Ob diese auch wirklich existiert, wird anschließend mittels der Methode verbunden () der Klasse Client überprüft. Spielbeginn: Bevor ein Spiel durch den Server begonnen werden kann, muss sich ein Client zu ihm verbinden. In der Klasse Server wurde hierzu ein Thread gestartet, der dies entsprechend erkennt (InetAdress iaIPClient) und die Methode clientHatVerbunden der Klasse Spielsteuerung aufruft. Dabei wird ihr die Endpunktadresse des Clients übermittelt. Auf dem Server-Rechner kann dadurch die IP-Adresse des Clients angezeigt werden. Ferner wird das Menü frei geschaltet, um einen Aufruf der Methode neuesSpielLokalGesetzt () zu ermöglichen, die ein neues Netzwerkspiel erstellt. Da es nur dem Server-Rechner obliegt, das Spiel zu eröffnen, wird bereits von der Oberfläche gewährleistet, dass der Spieler am Client-Rechner diese Methode nicht auslösen kann. Über die Methode ermittleNetzwerkspielBeginner () der Klasse Menuzugriff wird der Spielsteue- rung mitgeteilt, welcher Spieler den ersten Ball setzt. Des Weiteren wird über die Methode teileClientNachrichtMit (int iNachrichtenCode) der Klasse Server dem Client den Spielbeginn sowie den Spielbeginner mitgeteilt. Auf der Seite des Clients wird die Nachricht durch ein Objekt der Klasse KommunikationThread entgegengenommen, welches neuesSpielVonEntferntenRechnerAusgeloest (int iBeginner) die Methode aufruft. Das Spiel wird letztendlich durch den Aufruf der Methode neuesSpielstarten (int iBeginner) beim Client und Server gestartet (siehe Punkt 5.1 „Vorbereitung eines neuen Spieles“). 5.5.2. Neues Einzelspiel beginnen Im Einzelspielmodus ruft analog zum Netzwerkspiel der MenuErzeuger die Methode neuesSpielLokalGesetzt () auf. Es wird hierbei der Spieler 1 als Beginner Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 21 - festgelegt. Ebenfalls wird das Spiel mit der Methode neuesSpielstarten (int iBeginner) 5.5.3. begonnen. Bälle im Netzwerkspiel setzen Im Netzwerkspiel können die Bälle auf zwei verschiedene Art und Weise gesetzt werden. Es gilt hierbei prinzipiell zu unterscheiden, von wem der Ball gesetzt wurde. Einerseits können Bälle über die Klasse PanelErzeuger gesetzt werden. Dies ist stets der Fall, wenn der aktuelle Spieler am lokalen Rechner seinen Spielzug vornimmt. Es wird dabei die Methode ballLokalGesetzt (int iStab) ausgeführt. Diese kontrolliert die folgenden Bedingungen: Handelt es sich um ein Netzwerkspiel? Hat der Server ein neues Spiel gestartet? Ist der Spieler am Zug (aktueller Spieler)? Ist das Spiel bereits beendet? Nach erfolgreicher Überprüfung wird, je nach dem ob es sich um einen Server oder Client handelt, zuerst die Methode setzeBallBeiClient (int iStab) der Klasse Server bzw. setzeBallBeiServer (int iStab) der Klasse Client aufgerufen, um dem Gegenüber den zu setzenden Ball mitzuteilen. Andererseits können Bälle vom Gegenspieler über das Netzwerk gesetzt werden. Hierbei wird durch die Klasse KommunikationsThread ballvonEntferntenRechnerGesetzt (int iStab) die Methode ausgeführt. Hierbei bedarf es keiner außerordentlichen Prüfung, da diese beim entfernten Rechner vor der Entsendung der Nachricht getätigt wurde. Nicht nur aus diesem Grunde haben sich die Projektmitglieder dafür entschieden, auf Client- und Server-Seite die Spielsteuerung zu implementieren. Anschließend wird in beiden Fällen die Methode registriereBallUndZeigeAn (int iStab) ausgeführt. Diese veranlasst letztendlich das Setzen und Anzeigen des Balles (siehe Punkt 5.2 „Registrierung und Anzeigen der gesetzten Bälle“). Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 5.5.4. - 22 - Bälle im Einzelspiel setzen Im Einzelspielmodus ruft analog zum Netzwerkspiel der PanelErzeuger die Methode ballLokalGesetzt (int iStab) auf. Es erfolgen hierbei die Abfragen, wie unter Punkt 5.5.3 beschrieben. Schließlich wird erkannt, dass es sich um kein Netzwerkspiel sondern um ein Einzelspiel handelt Es werden keine Nachrichten versendet. Ebenfalls wird mit der Methode registriereBallUndZeigeAn (int iStab) 5.5.5. der Ball gesetzt. Netzwerkspiel abbrechen Grundsätzlich muss es für den Server und den Client gewährleistet sein, ein Netzwerkspiel jederzeit abzubrechen. Hierzu ruft der Client- oder Server-Rechner über die Klasse MenuErzeuger die Methode beendeNetzwerkspiel () auf. Die Methode nimmt die Unterscheidung vor, ob das ausgeführte Programm, als Server oder als Client fungiert. Entweder wird dann der Server-Socket oder der Socket des Client geschlossen und die TCP-Verbindung wird abgebaut. Ferner erfolgt ein Aufruf der Methode setzeNetzwerkSpielMenuZurueck MenuErzeuger, () der Klasse durch welche die Optionen im Menü in den Einzelspielzustand zu- rückgesetzt werden. Ebenfalls wird vorausgesetzt, dass ein Abbrechen der Verbindung beim gegenüberliegenden Rechner auch erkannt wird. Dies geschieht durch die Klasse KommnikationsThread, welche die Methode verbindungAbgebrochen () der Klas- se Spielsteuerung auflöst. Analog zu der Methode beendeNetzwerkspiel () werden die entsprechenden Sockets für den Server oder den Client geschlossen und es erfolgt eine Zurücksetzung des Menüs. 5.6. Beschreibung sonstiger Methoden der Spielsteuerung 5.6.1. Zugriff auf die Statustextzeile Durch die Methode uebernehmeStatusZugriff (PanelErzeuger peStatus) erhält die Spielsteuerung mit der Referenz auf das Objekt der Klasse PanelErzeuger den Zugriff auf die Statustextzeile im oberen Bereich des Spielfensters, um entsprechende Statusmeldungen dem Spieler des lokalen Rechners mitzuteilen. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 5.6.2. - 23 - Zugriff auf die Menüoptionen Durch die Methode setzeMenueZugriff (MenuErzeuger mneMenuZugr) erhält die Spielsteuerung mit der Referenz auf das Objekt der Klasse MenuErzeuger den Zugriff auf das Menü des Spielfensters, um entsprechende Menüpunkte zu debzw. aktivieren. Hiermit werden ungewollte Betätigungen von Menüunterpunkten durch den Spieler verhindert und somit die Spielsteuerung geschützt. 5.6.3. Ausschaltung der Musik und Geräusche Durch die Klasse MenuErzeuger wird die Methode setzeMusikInakiv () aufgerufen, um die eventuell spielende Hintergrundmusik auszuschalten. 6. Implementierung des Servers Der Server, welcher ein Programmteil des Computerspieles „Vier Gewinnt“ darstellt, ist in der Programmklasse Server, welche sich in der Datei „Server.java“ befindet, implementiert. Die Klasse liefert den für den Aufbau, den Betrieb und den Abbau einer Netzwerkverbindung notwendigen Server. Um einen reibungslosen Programmablauf zu gewährleisten, gilt es zu verhindern, dass der Hauptprozess nicht durch die Serverfunktionalität blockiert wird. Etwaige Blockierungen könnten beispielsweise auftreten, wenn der Hauptprozess warten müsste, bis sich ein Client mit einem Verbindungswunsch am Server anmeldet. Um dies zu vermeiden, werden Threads eingesetzt. Einerseits wird die Server-Klasse als Kind-Klasse von der Klasse Thread realisiert, andererseits wird für den Nachrichtenaustausch zwischen dem Server und dem Client die Klasse KommunikationsThread bereitgestellt. Diese Klasse befindet sich in der Datei „Kommuni- kationsThread.java“. 6.1. Erstellung des Servers Bei der Instanziierung des Objektes der Klasse Server erzeugt dieses ein Objekt der Klasse ServerSocket des Java-Pakets java.net.*. Bei diesem Vorgang erhält der Konstruktor der Klasse ServerSocket eine entsprechende Portnummer, welche durch die Klasse Einstellungen vorgegeben wird (Einstellungen.PORT_SERVER). Schließlich startet ein Thread, der dafür zuständig ist, eintreffende Verbindungsan- Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 24 - fragen von Clients entgegenzunehmen. Dies erfolgt durch den Aufruf der Methode accept () der Klasse ServerSocket in seiner run ()-Methode. Somit wurde der Server erstellt. 6.2. Aufgaben des Servers Nachfolgend werden die Aufgaben des Servers im Einzelnen erörtert: 6.2.1. Annahme von Verbindungen Richtet ein Client den Wunsch zum Aufbau einer Verbindung an den Server, so wird von dem in Punkt 6.1 beschriebenen Server-Thread die Verbindung akzeptiert und ein aktiver Socket für den Nachrichtenaustausch bereitgestellt. Ferner werden die für den Nachrichtenaustausch notwendigen Datenströme in Form von Objekten der Klassen ObjectOutputStream bzw. ObjectInputStream erzeugt. Der nicht mehr benötigte passive Server-Socket servSock für die Verbindungsaufnahme wird geschlossen. Bevor der Server-Thread terminiert, erzeugt dieser eine Instanz der Klasse KommunikationsThread, ankommende deren Aufgabe es ist, den neuen Socket auf eventuell Nachrichten Kommunikationthread abzuhören. Dem Konstruktor der Klasse wird hierbei der Datenstrom ObjektInputStream obInStr sowie eine Referenz der Spielsteuerung übergeben. Um der Spielsteuerung eine Kontrollfunktion über den Zustand des Servers bereitzustellen, wird die Methode istServerErstellt () implementiert. Hierbei wird abgefragt, ob der Socket für die Verbindung sich in einem aktiven Zustand befindet. 6.2.2. Nachrichtenaustausch Nachrichten werden stets in Form von serialisierten Objekten versendet und empfangen. Hierzu wurde die Klasse Nachricht bereitgestellt, welche die Schnittstelle Serializable implementiert. Das Nachrichten-Objekt wird mit Hilfe Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 25 - der Klasse KommunikationsThread über die im Punkt 6.2.1 beschriebenen Datenströme versendet oder empfangen. Maßgebend für die Erstellung einer speziellen Nachrichtenklasse und der Serialisierung ihrer Objekte war, auf möglichst einfacher Weise das Format der Nachricht je nach Bedarf variabel gestalten zu können. Erst zu einem späteren Zeitpunkt der Projektentwicklung zeigte sich, dass für den Nachrichtentransport eine einfache Integer-Variable ausreichend ist. Die Klasse KommunikationsThread stellt zwei Konstruktoren bereit. Diese wurden implementiert, um den Thread für den Datenempfang vom Thread für den Datenversand zu unterscheiden, indem beiden Objekten ein eigener Name zugeteilt wird. Zugleich werden den Threads im Parameter des Konstruktors den für ihn bestimmten Datenstrom für den Datenempfang bzw. –versandt übergeben. Datenempfang: Der Thread zum Empfangen von Daten, welcher durch den Server-Thread der Klasse Server gestartet wird, liest in einer while-Schleife seiner run ()Methode ankommende Nachrichten-Objekte aus dem ObjektInputStream. Anschließend liest er mit der Methode holeNachrichtCode () der Klasse Nachricht das empfangene Objekt aus. Je nach (Integer-)Wert wird die Nachricht in entsprechenden if-Anweisungen ausgewertet, um die von der Spielsteuerung zur Verfügung gestellten Schnittstellen anzusprechen. Es werden hierfür zwei Methoden bereitgestellt: Einerseits kann mit der Methode neuesSpielVonEntferntenRechnerAusgeloest (int iNachrichtCode) ein neues Spiel durch den Server-Rechner beim Client ausgelöst werden. Mögliche Nachrichten-Codes sind die zwei Konstanten der Spielsteuerung NEUES_NETZWERKSPIEL_SERV (der Server-Rechner macht den ersten Zug) und NEUES_NETZWERKSPIEL_CLIE (der Client-Rechner beginnt). Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung Andererseits (int iStab) wird mit der - 26 - Methode ballVonEntferntenRechnerGesetzt der Klasse Spielsteuerung veranlasst, dass die vom entfernten Rechner gesetzte Kugel, am lokalen Rechner registriert und angezeigt wird. Dazu wird der als Nachricht empfangene Stab- bzw. Spaltenindex als Parameter iStab übergeben. Datenversand: Wie bereits in Punkt 5.5.3 „Bälle im Netzwerkspiel setzen“ beschrieben, wird von der Klasse Spielsteuerung veranlasst, Bälle beim entfernten Rechner zu setzen. Im Falle des Server-Rechners setzeBallBeiClient (int iStab). erfolgt der Aufruf der Methode Mit Hilfe des Parameters iStab an den Kon- struktor der Klassen Nachricht wird das Nachrichten-Objekt nSendung erzeugt. Zur Instanziierung des Kommunikations-Threads thSender, wird dieser mit den Werten obOutStr und nSendung initialisiert. Anschließend wird die run ()Methode der Klasse KommunikationsThread aufgerufen. Hier schreibt der Thread mittels der Methode writeObject (Object obj) der Klasse ObjectOutputStream in den Verbindungssocket des Servers und terminiert. 6.3. Beenden des Servers Mittels der Methode Spielsteuerung in schliesseSocket den verbindungAbgebrochen () () Methoden der Klasse Server beendeNetzwerkSpiel wird () der bzw. die Möglichkeit gegeben, eine bestehende Verbindung zum Client abzubrechen, indem der in Punkt 6.2.1 „Annahme von Verbindungen“ erstellte Socket geschlossen wird. Anschließend wird in der Spielsteuerung dem Server-Objekt sServer der Wert null zugewiesen. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 27 - 7. Einsatz von Musik und Geräuschen Um das Spielerlebnis und die Animation des Benutzers zu verbessern, wurde das in Punkt 2.1 „Definition der Projektziele“ von uns genannte Erweiterungsziel, der Einsatz von musikalischer Untermalung, realisiert. Hierfür wurde die Klasse Musikspieler implementiert. 7.1.1. Auswahl der Audiodaten Im Computerspiel des Projekts „Vier Gewinnt“ werden drei verschiedene Audiodateien verwendet, dessen Quellen im Punkt 13.3 „Quellenverzeichnis“ genannt werden. Die „Vier Gewinnt“-Musik: Es handelt sich hierbei um die Datei „viergew22kHzMono8bit.wav“, welche sich unter dem Pfad CD-Laufwerk:\4G_Programm\sounds\ auf der mitgelieferten Projekt-CD befindet. Diese Datei wird abgespielt, wenn das Programm mit Musikund Tonunterstützung gestartet wird (siehe Punkt 8.1 „Das Hauptfenster“) bzw. wenn ein Spiel durch einen Spieler gewonnen wird. Geräusch „Feld löschen“: O. g. Geräusch wird durch Abspielen der Datei „FeldLoeschen.wav“ erzeugt und befindet sich unter dem zuvor genannten Pfad. Das Geräusch ertönt, wenn ein neues Spiel gestartet wird und sich auf dem Spielbrett Bälle des letzten Spieles befinden, die zu löschen sind. Geräusch „Ball setzen“: Zum Setzen eines Balles ertönt ein Geräusch, welches mit der Audiodatei „BallSetzen.wav“ erzeugt wird. Die Datei befindet sich ebenfalls unter dem o. g. Pfad. Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 7.1.2. - 28 - Bearbeitung der Audiodaten Für das Abspielen von Musik und Geräusch wurde von uns auf die Klasse AudioClip des Pakets java.applet.* zurückgegriffen. Diese unterstützt das Ab- spielen von Dateien des Formats *.au, *.wav, *.aif und *.mid. Weil es sich bei Audio im au-, wav-, und aif-Format um unkomprimierte Daten handelt, war es notwendig, eine explizite Bearbeitung der Audiodaten vorzunehmen. Hierzu wurde die o. g. „Vier Gewinnt“-Musik, welche von einer CD stammte und somit eine Samplerate von 44,1 kHz besitzt und mit 16 Bit quantisiert ist, entsprechend verändert, um bezüglich des Speicherbedarfs wesentlich kompakter zu werden. Zur Änderung der Audiodatei wurde die Samplerate auf 22 kHz und die Quantisierung auf 8 Bit heruntergesetzt. Zudem wurden beide Stereo-Kanäle auf einen Kanal (Mono) zusammengefügt, so dass das notwendige Speichervolumen für alle drei Formate auf 118 kByte beschränkt werden konnte. 7.1.3. Beschreibung der Klasse Musikspieler Konstruktor: Beim Aufruf des Konstruktors der Klasse Musikspieler wird für jede Audiodatei jeweils ein URL-Objekt erzeugt. Diese werden als Parameter der statischen Methode newAudioClip (URL url) der Klasse Applet übergeben, um entsprechende Objekte der Klasse AudioClip zu instanzieren. Somit werden die Audiodaten für das Programm bereitgestellt. Ferner wird im Konstruktor gegebenenfalls die „Vier Gewinnt“-Musik gestartet. Sonstige Methoden: Im Übrigen dienen nachfolgende Methoden dazu, um die oben bereitgestellten Audiodaten abzuspielen und zu stoppen: spieleSoundSetzeBall () spieleSoundLoescheFeld () spieleVierGewinntMusik () deaktiviereVierGewinntMusik () Bearbeitet von: Raymund Witzel Matr.-Nr. 160 050 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 29 - 8. Zweidimensionale Fensterelemente (Graf. Oberfläche) Die Grafische Oberfläche des Computerspieles „Vier Gewinnt“ ist in zwei komplexe Bereiche unterteilt. Der erste Bereich beschäftigt sich mit den zweidimensionalen Fensterelementen. Diese Elemente werden durch die Erzeugung des Hauptfensters, den Aufbau des Menüs und der Gestaltung des eigentlichen Fensterinhalts, welcher aus den Panels gebildet wird, realisiert. Der zweite komplexe Bereich behandelt die dreidimensionale Spielszene, welche durch die Programmierschnittstelle Java3D API realisiert wurde und in der Mitte des Anwendungsfensters dargestellt wird (siehe Punkt 9 „Dreidimensionale Spielszene (Graf. Oberfläche)“). Der zweidimensionale Fensteranteil besteht aus den folgenden Elementen: 8.1. Das Hauptfenster Das Hauptfenster, welches eine Größe von 550 Pixeln (in der Höhe) x 505 Pixeln (in der Breite) aufweist, beinhaltet alle optischen Elemente des Spieles „Vier Gewinnt“. Es wird durch die Klasse VierGewinnt repräsentiert, die sich in der Datei „VierGewinnt.java“ befindet. Diese Klasse wird künftig als „Hauptklasse“ bezeichnet. Sie erbt von JFrame und enthält zudem das Hauptprogramm (main Für die Implementierung javax.swing.JFrame, java.awt.* des Hauptfensters müssen ()-Methode). die Pakete und java.awt.event.* importiert werden. Die Instanziierung des Hauptfensters geschieht im Hauptprogramm. Diesem kann der Parameter -musikAus übergeben werden, um die Musik- bzw. Tonunterstützung zu unterbinden. Weiterhin beinhaltet das Hauptprogramm eine anonyme innere Klasse, die von der Klasse WindowAdapter abgeleitet wird und als Ereignisempfänger fungiert. Mit Hilfe ihrer einzigen Methode windowClosing (WindowEvent e) wird das Programm beendet, wenn das Hauptfenster geschlossen wird. Die Hauptklasse VierGewinnt erzeugt in ihrem Konsturktor durch den Aufruf der Methode erzeugeFensterInhalt () alle erforderlichen Objekte, die den Fensterinhalt darstellen. Für den zweidimensionalen Fensterinhalt sind dies die Objekte pePanels Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung der Klasse PanelErzeuger und - 30 - menMenu der Klasse MenueErzeuger. Das Objekt pePanels repräsentiert ein Panel, welches mit der Anweisung this.getContentPane().add (pePanels) dem Hauptfenster übergeben wird. Hierbei wird ein Container-Objekt ContentPane zurückgegeben, welches über die Methode add(JPanel jpObj) das Objekt der Klasse PanelErzeuger aufnimmt. Des Weiteren erhält das Hauptfenster über seine Methode setJMenuBar (JMenuBar jmbObjekt) das Menü in Form des Objektes menMenu zugeordnet. Ferner implementiert die Klasse VierGewinnt die Zusammensetzung des Java 3DSzenengraphen, auf den gesondert in Punkt 9.2 „Aufbau des Szenengraphen“ eingegangen wird. 8.2. Das Fenstermenü Das in Punkt 8.1 bereits genannte Objekt menMenu stellt das Menü des Fensters zur Verfügung und ist eine Instanz der Klasse MenuErzeuger (diese erbt von JMenuBar), welche in der Datei „MenuErzeuger.java“ zu finden ist. Im Konstruktor der Klasse werden die Menüunterpunkte benannt und ihren Menübereichen hinzugefügt, welche ihrerseits dem Haupt-Objekt MenuErzeuger angehängt werden. Wird das Programm ohne die im Punkt 8.1 beschriebene Musik- und Tonunterstützung gestartet, wird auf den Untermenüpunkt JMenuItem mniTonAnAus verzichtet, der eine De-/Aktivierung der Musik zulässt. Um auf Benutzeraktionen reagieren zu können, wird für jedem der einzelnen Menüpunkte ein Empfänger für Mausereignisse (ein Objekt der inneren Klasse actionEventHandler) (ActionEvent e) e zugeordnet, welche in der Methode actionPerformed entgegengenommen werden. Anhand des übergebenen Objektes kann festgestellt werden, welcher Menüpunkt der Auslöser des Ereignisses war. Entsprechend dem Menüpunkt wird der vorgesehen Code ausgeführt, der u. a. die Methoden der Klasse Spielsteuerung aufruft. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 31 - Besonders erwähnenswert ist der auszuführende Quellcode für den Menüpunkt mniNetzwSpielTeilnehmen. Vor der Erzeugung des Clients durch die Methode erzeugeClient (InetAddress addrServer) wird die Adresse des Servers durch den Spieler angegeben. Hierzu wird ein Dialogfenster geöffnet, in das die IP-Adresse bzw. der Hostname des Servers einzugeben ist. Mittels der Methode getByName (String hostName) der Klasse InetAddress wird eine Adressauflösung des einge- gebenen Rechnernamens vorgenommen und festgestellt, ob der Server-Rechner im Netzwerk überhaupt erreichbar ist. Ist dies nicht der Fall wird eine „Exception“ (Ausnahme) der Klasse UnknownHostException abgefangen und dem Spieler eine entsprechende Statusnachricht mitgeteilt. Es findet somit eine Eingabenprüfung des Benutzers statt. Im Folgenden wird gesondert auf die Methoden der Klasse MenuErzeuger eingegangen: setzeNeuesSpielMoeglich (boolean bSchalter): Diese Methode stellt eine Schnittstelle für die Klasse Spielsteuerung dar, durch die es ermöglicht wird, den Untermenüpunkt Neues Spiel starten während der Zeit des Netzwerkspieles zu deaktivieren, in der der Server-Rechner einen Server erzeugt, aber noch kein Client eine Verbindung zu ihm aufgenommen hat. In diesem Zeitraum darf der Server-Rechner kein neues Spiel starten. ermittleNetzwerkspielBeginner (): Die Methode öffnet ein Dialogfenster, das den Benutzer des Server-Programms auffordert, den Beginner des Netzwerkspieles zu ermitteln (siehe Punkt 5.5.1 „Neues Netzwerkspiel beginnen“). Diese Methode wird von der Spielsteuerung aufgerufen und in dieser Klasse implementiert, um die Logik der Spielsteuerung von der Oberfläche zu trennen. Rückgabewerte sind deshalb die Konstanten der Spielsteuerung NEUES_NETZWERKSPIEL_SERV, NEUES_NETZWERKSPIEL_CLIE und KEIN_NETZWERK_SPIEL. Die Bedeutung dieser Werte kann aus dem Punkt 6.2.2 „Nachrichtenaustausch“ (Datenempfang) entnommen werden. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 32 - setzeNetzwerkSpielMenuZurueck (): Die Methode setzt die durch die Spielsteuerung veränderten Menüpunkte nach einem Netzwerkspiel wieder in den Ursprungszustand zurück. 8.3. Der Fensterinhalt Das in Punkt 8.1 bereits genannte Objekt pePanels bildet den Inhalt des Fensters und ist eine Instanz der Klasse PanelErzeuger, welche von JPanel erbt und in der Datei „PanelErzeuger.java“ zu implementiert wurde. 8.3.1. Die Panels Der Konstruktor der Klasse veranlasst durch die Methode initialisiere () den Aufbau des Fensterinhalts, welcher aus insgesamt fünf Objekten der Klasse JPanel und von vier Objekten der Klasse BildKomponente gebildet wird. Die An- ordnung dieser Panels gestaltet sich nach folgendem Schaubild: Abbildung 11: Anordnung der Panels im Hauptfenster Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 33 - Das Haupt-Panel jpGesamt bietet, wie aus der Abbildung 11 zu entnehmen ist, den Untergrund für das eigentliche Inhalts-Panel jpInhalt sowie die vier Instanzen bkLinks, bkRecht, bkUnten und bkOben (siehe Punkt 8.3.4). Das Panel jpInhalt wird wiederum in drei Bereiche unterteilt: Der obere Bereich wird vom Ob- jekt jpInhaltOben ausgefüllt, welches das Textfeld für die Statusmeldung aufnimmt (siehe Punkt 8.3.3). Der mittlere Bereich enthält das Panel jpMitte3D, in welchem die 3D-Grafikausgabe vorgenommen wird. Diese wird im Konstruktor der Klasse als Parameter Canvas canv3D übergeben und genanntem Panel hinzugefügt. Der untere Bereich enthält das Panel jpInhaltUnten, in welchem die sieben „Buttons“ zum Setzen der Bälle platziert werden (siehe Punkt 8.3.2). Allen Panels des Hauptfensters werden (LayoutManager mgr) über die Methode setLayout das Null-Layout zugewiesen. In unserem Fall verwendet das Hauptfenster also keinen „Layout-Manager“, sondern die Anwendung übernimmt die Positionierung und Festlegung der Größe der Komponente mittels der Methode setBound (int x, int y, int width, int height). 8.3.2. Die Ansteuerung der Stäbe Für die Ansteuerung der Stäbe im unteren Bereich jpInhaltUnten werden die sieben Objekte jbStab0 bis jbStab6 der Klasse JButton aufgenommen. Analog zu den Menüpunkten der Klasse MenuEreuger ist hier der Einsatz eines Ereignisempfängers für die Maus notwendig. Dieser wird in der inneren Klasse actionEventHandler implementiert, dessen Instanzen den o. g. „Buttons“ mit Hilfe der Methode addActionListener (ActionListener actl) zugeordnet werden. Um der Klasse Spielsteuerung mitzuteilen, an welchem Stab ein Ball zu setzen ist, bekommt der PanelErzeuger deren Referenz im Konstruktor überliefert. Somit kann in der Methode actionPerformed (ActionEvent e) des Ereignisempfängers actionEventhandler der Index des Stabes an die Spielsteuerung übergeben werden. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 8.3.3. - 34 - Statusmeldungen Im Konstruktor der Panel-Klasse werden Eigenschaften (die Position und das Aussehen), für das Textfeld JLabel jlSpielstatus festgelegt, dass dem Spieler Hinweise zum Spielgeschehen anzeigt. Über die Methode setzeStatusMeldung (String strStatusMeldung) wird eine Schnittstelle für die Klasse Spielsteuerung geschaffen, wobei der String strStatusMeldung die entsprechende Mitteilung enthält. 8.3.4. Erläuterung der Klasse BildKomponente Die Klasse BildKomponente realisiert ergänzende Fensterelemente in Form von Panels, welche in der Lage sind, die Bilddateien für den Aufbau des „blauen Fensterrahmens“ aufzunehmen. Sie ist in der Datei „BildKomponente.java“ implementiert und wurde eingeführt um die folgenden Problematiken zu beseitigen: Einerseits musste gewährleistet sein, eine Position des Bildes innerhalb des Panels anzugeben. Hierzu erbt die Klasse von JPanel, so dass das Null-Layout verwendet werden kann, wodurch eine Positionierung innerhalb des darunter liegenden Panels möglich ist. Andererseits wurden die Bilder nach dem Programmstart nicht oder nur teilweise angezeigt, was auf einen zu zeitintensiven Ladevorgang zurückzuführen war. Zur Problemlösung wurde das Objekt mtLadevorgang der Klasse MediaTracker verwendet. Dieses gewährleistet eine Überwachung des Ladevorgangs, so dass die Bilder wie vorgesehen angezeigt werden können. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 35 - 9. Dreidimensionale Spielszene (Graf. Oberfläche) 9.1. Allgemeine Grundlagen Die dreidimensionale Spielszene des Projektes „Vier Gewinnt“ wurde mit Hilfe der Programmierschnittstelle Java 3D realisiert. Diese Grafikschnittstelle bietet den enormen Vorteil, dass sie sich die Plattformunabhängigkeit von Java zu Eigen macht. Java läuft auf den verschiedensten Betriebssystemen, ohne das die Anwendung neu übersetzt werden muss. In einem Java 3D-Programm werden Instanzen von 3D-Objekten gebildet, welche in einem s. g. Szenengraphen platziert werden. Dieser Szenengraph repräsentiert eine Datenstruktur, welche Informationen der 3DObjekte über Geometrie, Licht, Position und Aussehen abspeichert und eine virtuelle Welt (das „Virtuelle Universum“) modelliert. Die folgende Abbildung Bild entstammt der Quelle [Qi] und veranschaulicht die Grundstruktur eines Szenengraphen: Abbildung 12: Aufbau eines Szenengraphen Ein Szenengraph besteht strukturell aus Kanten und Knoten. Ein Knoten, welcher in der Literatur auch als Gruppen-Knoten bezeichnet wird, hat einen Vater-Knoten und kann beliebig viele Kind-Knoten haben. Ein Blattknoten hat nur einen Vater-Knoten, aber keine Kind-Knoten. Die Kanten zwischen den Knoten werden als Beziehungen zwischen den Datenelementen dargestellt. [Qii] Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 36 - Die Wurzel eines Szenengraphen ist der Knoten „Virtual Universe“ und dient dazu den Graphen an eine Ausgabefläche zu binden. In Java 3D wird dieser Knoten als Objekt der Klasse VirtualUniverse realisiert. Ein Szenengraph kann stets nur einen dieser Wurzelknoten besitzen. An diesen Wurzelknoten können ein oder mehrere Locale-Objekte angehängt werden. Diese dienen als Bezugssystem für die räumli- che Platzierung von 3D-Objekten im Virtuellen Universum, d. h. es wird mit ihm ein Ursprung eines 3-achsigen Koordinatensystems festgelegt. Im Projekt „Vier Gewinnt“ wird lediglich ein „Locale“-Knoten eingesetzt, welcher mittels der Java 3DKlasse Locale zur Verfügung gestellt wird. [Qiii] An den „Locale“-Knoten werden die Teilgraphen „Content Branch“ und „View Branch“ eingehängt, wobei der erste Teilgraph mehrmals existieren kann. Der „Content Branch“-Zweig beschreibt die Geometrie, das Aussehen und die Positionierung sowie das Verhalten und die Beleuchtung seiner Objekte. Dieser enthält alle Objekte, die in der Szene vorkommen. In dem Zweig „View Branch“ wird die Ansicht des Benutzers auf die Szene beschrieben, u. a. wird die Position der Kamera in dem Koordinatensystem festgelegt. Die Wurzelknoten der beschriebenen Teilbäume werden jeweils durch einen „BranchGroup“-Knoten repräsentiert. In Java 3D sind dies Instanzen der Klasse BranchGroup. [Qiv] Der „BranchGroup“-Knoten kann verschiedene Objekte aufnehmen. Eines dieser Objekte ist der „TransformGroup“ Knoten, mit welchem die Position und die Skalierung von geometrischen Objekten bzw. der Ansicht (Kamera) relativ zum Ursprung bestimmt werden kann. [Qv] Die „TransformGroup“-Knoten verwenden dabei die „Tranform3D“-Objekte, welche Translationen, Rotationen oder Skalierungen von geometrischen Objekten mit Hilfe von Matrizen ermöglichen. [Qvi] Geometrische Objekte werden durch den Blattknoten „Shape3D“ spezifiziert. Dieser Knoten besitzt einerseits die Referenz zu den geometrischen Daten seines Objektes und andererseits das Erscheinungsbild seines Objektes, welches über die Attribute Farbe, Material oder die Textur bestimmt werden. [Qvii] Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 37 - Ein weiterer Gruppen-Knoten ist der „Switch“-Knoten, welcher es erlaubt, während der Laufzeit dynamisch, einen oder mehrere Teilbäume auszuwählen, dessen Objekte zu „rendern“ sind. Im Projekt „Vier Gewinnt“ wurden zwei solcher Knoten verwendet, die für die Visualisierung der Bälle der einzelnen Spieler verantwortlich sind (siehe Punkt 9.6 „Erzeugung und Kontrolle der Bälle“). Zur Ansteuerung dieser „Switch“-Knoten kann eine Bit-Maske verwendet werden, die es erlaubt, die entsprechenden Teilbäume (in unserem Falle die Bälle) anzusprechen. Um die Bit-Maske zu setzen, wird die Klasse BitSet verwendet, welche die Indizes der zu wählenden Teilbäume spezifiziert. [Qviii] Abschließend wird explizit auf einige Knoten des „View Branch“-Teilbaumes eingegangen, die sich von denen des „Content Branch“ unterscheiden: Das „View-Platform“-Objekt ist ein Blatt-Knoten („Leaf“-Knoten) und definiert die virtuelle Kamera und damit die Ansicht der Szene. [Qix] Das „View“-Objekt ist kein Knoten-Objekt und gehört somit nur indirekt zum Szenengraph. Es selbst und die Objekte mit denen es verbunden ist, besitzen alle Information, die zum „Rendern“ einer Szene notwendig sind. [Qx] Das „Screen3D“-Objekt enthält alle Parameter über den physikalischen Bildschirm. [Qxi] Das „Canvas3D“-Objekt dient als Schnittstelle zwischen dem „View“- und dem „Screen3D“-Objekt und speichert alle Parameter der Zeichenfläche, die „gerendert“ werden sollen. [Qxii] Das „PhysicalBody“-Objekt beinhaltet allgemeine Kalibrierungsinformationen. [Qxiii] Das „PhysicalEnvironment“-Objekt beinhaltet Kalibrierungsinformationen, die die physikalische Umgebung betreffen. [Qxiv] Hinweis: Die oben benutzen Fachbegriffe werden so in der Literatur verwendet und wurden aus Verständnisgründen nicht ins Deutsche übersetzt. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 38 - 9.2. Aufbau des Szenengraphen Der Aufbau des Szenengraphen, welcher für die Gestaltung der grafischen 3DOberfläche des Spieles verantwortlich ist, wird in der Programmklasse VierGewinnt, die sich in der Datei „VierGewinnt.java“ befindet, zusammengefügt. Wie in dem Punkt 9.1 „Allgemeine Grundlagen“ verdeutlicht, wird in Java 3D für die Modellierung des 3D-Raumes die Zusammensetzung eines Szenengraphen vorausgesetzt. Für das Projekt „Vier Gewinnt“ wurde deshalb ein solcher Szenengraph erstellt, welcher in der Anlage 2 eingesehen werden kann. Die hier dargestellten Knoten wurden zum besseren Verständnis mit den entsprechenden Klassen- und Objektnamen des Projektes bezeichnet. Auf diese Anlage wird im Laufe der nachfolgenden Dokumentation wiederholt Bezug genommen. Mit der Methode erzeugeFensterInhalt () der Klasse VierGewinnt veranlasst der Konstruktor den Aufbau des Szenengraphen. Zuerst wird das Wurzel-Objekt vUniversum der Klasse VirtuealUniverse instanziiert, welches das Virtuelle Univer- sum darstellt. Als nächstes erfolgt die Bereitstellung des „Locale“-Knoten, durch das Objekt lLocaleObj der Klasse Locale. Mittels der Methode addBranchGraph (BranchGroup bgKnoten) können diesem Objekt die einzelnen Äste des Szenengra- phen, welche jeweils einen „BranchGroup“-Knoten als Wurzel besitzen, hinzugefügt werden. Zunächst wird das Objekt belicht der Klasse Belichtung als „BranchGroup“-Knoten erzeugt (siehe Punkt 9.4 „Festlegen der Belichtung“) und dem „Locale“-Knoten angehängt. meineAnischt der Klasse Ansicht erzeugt, welchem die Referenz des Objektes der Des Weiteren wird der BranchGroup-Knoten Klasse Canvas3D übergeben wird. Diese wird im „View-Branch“-Teilbaum benötigt (siehe Punkt 9.3 „Gestaltung der Ansicht“). Schließlich werden die Teilgraphen für die geometrischen und sichtbaren Objekte erstellt. Als Erstes wird der „BranchGroup“-Knoten der Klasse Spielbrett geschaffen (siehe Punkt 9.5 „Aufbau des Spielbretts“), welcher durch die Referenz spbr repräsentiert wird. Als Zweites werden die Bälle erzeugt und deren Kontrolle ermöglicht. Hierzu wird eine Instanz der Klasse Ballkontrolle gebildet, die einen weiteren „BranchGroup“-Knoten darstellt (siehe Punkt 9.6 „Erzeugung und Kontrolle der Bälle“). Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 39 - Der Szenengraph ist somit vollständig zusammengesetzt. Der Vorgang des „Renderns“, der eine Angelegenheit des „View-Branch“-Teilbaumes ist, wird durch die Referenz des Canvas3D-Objektes mit seiner Methode startRenderer () angestoßen. Abschließend ist zu erwähnen, dass die Hauptklasse der Spielsteuerung die Kontrolle über die Bälle in Form des Objektes ballktrll der Klasse Ballkontrolle übergibt. 9.3. Gestaltung der Ansicht Die Gestaltung der Ansicht betrifft den Teilgraphen, der in der Literatur auch als „View-Branch“ bezeichnet wird. Der „View-Branch“-Ast des Projektes „Vier Gewinnt“ wird in der Programmklasse Ansicht realisiert, die sich in der Datei „Ansicht.java“ befindet und in der Anlage 2 als roter Teilbereich gekennzeichnet ist. Die Klasse erbt von der Klasse BranchGroup und stellt einen solchen Knoten dar, der in den „Locale“-Knoten eingehängt wird. Sie beschreibt die Sicht des Benutzers auf die Szene und legt somit die Eigenschaften der Kamera fest. Im Konstruktor der Klasse werden alle wichtigen Elemente des „View-Branch“Teilbaumes instanziiert. Lediglich das Canvas3D-Objekt wird wie in Punkt 9.2 erwähnt in der Klasse VierGewinnt erzeugt und im Konstruktor übergeben. Dies ist notwendig, weil die Klasse PanelErzeuger ebenfalls diese Referenz benötigt (siehe Punkt 8.3.1 „Die Panels“). Zunächst werden die Objekte phyBody der Klasse PhysicalBody sowie phyEnv der Klasse PhyscalEnvironment als auch die Instanz view der Klasse View erzeugt. Dem View-Objekt werden schließlich die vorgenannten Objekt sowie das Objekt c3d der Klasse Canvas3D gesetzt bzw. hinzugefügt. Weiterhin wird der Blatt-Knoten viewplatform der Klasse ViewPlatform instanziiert und dem view-Objekt angehängt. Zudem wird durch die Klasse Ansicht die Rotation der Kamera durch die Maus ermöglicht. Hierzu wird dem „BranchGroup“-Wurzelknoten ein „TransformGroup“Knoten anhängt, der durch das Objekt trGrKameraMaus der Klasse TransformGroup Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 40 - gestellt wird. Dieser verwendet den „Behavior“-Blattkonten mausRot der Klasse MouseRotate, der für die Benutzerinteraktion zuständig ist. Um die Rotation der Ka- mera durch die Maus zu ermöglichen, ist die Festlegung des s. g. „Scheduling“Bereiches notwendig. Dieser spezifiziert einen begrenzten Raum von beliebiger Größe und legt fest, wann ein „Behavior“ überhaupt für die Ausführung berücksichtigt wird. Dies ist der Fall, wenn der Aktivationsbereich der Kamera sich mit dem „Scheduling“-Bereich des „Behaviors“ schneidet. [Qxv] Ein „Behavior“ ist eine Verbindung einer Interaktion und einer daraus resultierenden Aktion. [Qxvi] Für die Ansicht des Benutzers ist es weiterhin notwendig, eine Anfangsposition der Kamera festzulegen. Dazu wird dem o. g. „TransformGroup“-Knoten ein weiterer gleichartiger Knoten (dieser wird durch das Objekt trGrKamera bestimmt) angehängt. Dieser verwendet den Knoten trKameraStart der Klasse Transform3D, der die Anfangsposition (x = 0.0, y = 10.0, z = 60.0) festlegt. 9.4. Festlegen der Belichtung Die Festlegung der Eigenschaften des Lichtes wird in der Programmklasse Belichtung, die sich in der Datei „Belichtung.java“ befindet, vorgenommen. In der Anlage 2 wird der entsprechende Szenenteilgraph als lila Teilbereich gekennzeichnet. Die Klasse Belichtung erbt wiederum von der Klasse BranchGroup und wird in den „Locale“-Knoten eingehängt. Für die Darstellung der Szene des Spieles werden die drei Elemente ambientes Licht, direktionales Licht sowie der Hintergrund benötigt. Auf diese wird nachfolgend näher eingegangen: 9.4.1. Ambientes Licht Das ambiente Licht simuliert die allgemeine Menge an Umgebungslicht, welches von anderen Objekten auf ein Objekt geworfen wird. Es besitzt dieselbe Intensität an allen Stellen der Objekte, als würde es gleichmäßig aus allen Richtungen beleuchtet. [Qxvii]. Im Konstruktor der Klasse Belichtung wird ein Blatt-Knoten für die Simulation des Umgebungslichtes instanziiert, welches durch das Objekt ambLight der Klasse AmbientLight umgesetzt wird. Diesem wurde das Farbobjekt cAmbLicht (ein grauer Farbton) der Klasse Color3f zugewiesen, welches sich in Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 41 - der global zugänglichen Klasse Einstellungen befindet. Im Punkt 9.6.1 „Ballerzeugung“ wird auf die Auswirkung des ambienten Lichtes auf die BallObjekte noch näher eingegangen. Um das ambiente Licht in der Umgebung einzugrenzen, wird das Objekt gsLichtgrenzen der Klasse BoundingSphere erzeugt und dem Licht mittels der Methode setInfluencingBounds (BoundingSphere bsObj) zugewiesen. 9.4.2. Direktionales Licht Das direktionale Licht simuliert die Lichteinwirkung einer sehr weit entfernten Lichtquelle analog der Sonne. Es wird als unendlich weit entfernt angenommen und hat keine direkte Position. [Qxviii] Im Gegensatz zum ambienten Licht verlaufen alle Lichtstrahlen parallel in die Richtung, welche durch einen Vektor bestimmt wird. Seine Richtung verläuft vom Ursprung zu den Koordinaten des Punktes P. Dieser Vektor wird durch das Objekt vRichtung der Klasse Vektor3f gesetzt. Das nachfolgende Schaubild visualisiert das Ball-Objekt im direktionalen Licht: Y Direktionales Licht Richtungsvektor X P (-1.5, -1.0, -0.5) Z Abbildung 13: Richtung des direktionalen Lichtes Das direktionale Licht wird mit Hilfe des Objektes lichtstrahl der Klasse DirectionalLight realisiert. Der Farbton cDirLicht wird wiederum in der Einstel- lungsklasse bestimmt. Analog zu dem Punkt 9.4.1 wird dem direktionalen Licht mittels der Klasse BoundingSphere eine Lichtgrenze gesetzt. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 9.4.3. - 42 - Der Hintergrund Der Hintergrund der dreidimensionalen Spielszene wird durch die Klasse Background gebildet. Einem Objekt bgHintergr wird hierbei die Farbe cHintergrundfarbe aus der Klasse Einstellungen zugeordnet. Auch dieser wird durch das Objekt gsLichtgrenzen der Klasse BoundingSphere eingegrenzt. 9.5. Aufbau des Spielbretts Der Aufbau des Spielbrettes, auf welchem das Spielgeschehen stattfindet, ist in der Programmklasse Spielbrett, die sich in der Datei „Spielbrett.java“ befindet, implementiert. Das Spielbrett wird aus zwei „Brettern“ (flache Quader), die in einem Winkel von 90 Grad zueinander stehen (Rotation um die X-Achse), zusammengesetzt. Weiterhin nimmt das Spielbrett die Spielstäbe auf, auf die die Bälle „gesteckt“ werden. In der Anlage 2 wird der entsprechende Szenenteilgraph als grüner Teilbereich gekennzeichnet, dessen Wurzelknoten die o. g. Klasse darstellt. Diese Klasse erbt von BranchGroup und wird in den „Locale“-Knoten eingehängt (siehe Punkt 9.2 „Aufbau des Szenengraphen“). Der Konstruktor der Klasse Spielbrett übernimmt dabei die Aufgabe, die beiden Quader und die zugehörigen Stäbe zu erzeugen: 9.5.1. Die Einzelbretter Zuerst wird beiden Einzelbretter ein Erscheinungsbild zugeteilt, das durch das Objekt apBrett der Klasse Appearance vertreten wird. Diesem Erscheinungsbild wird über die Methode setMaterial (Material mObj) ein Material zugewiesen. Nähere Erläuterungen zu dem Thema Materialeigenschaften zu Objekten sind dem Punkt 9.6.1 „Ballerzeugung“ zu entnehmen. Des Weiteren erhält das Erscheinungsbild eine Textur, die über die Methode lieferTexture (String strPfad) Bearbeitet von: André Och bereitgestellt wird. Der übergebene Parameter Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung strPfad - 43 - enthält einen relativen Pfad unterhalb des Programmverzeichnisses zu einer Bilddatei. Für diese Datei wird ein entsprechendes „Handle“ fBildDatei der Klasse File bereitgestellt, um den Bildpuffer BufferedImage biBild mit Bilddaten zu füllen. Hierzu wird die statische Methode read (File fObj) der Klasse ImageIO benutzt. Um eine neue Textur zu erstellen, wird einer Instanz der Klasse TextureLoader der Bildpuffer übergeben und dessen Methode getTexture () an- schließend aufgerufen. Die neu erzeugte Textur wird dem Erscheinungsbild apBrett durch die Methode setTexture (Texture txObj) zugeführt. Die nun zu erstellenden Einzelbretter des Spielbretts stellen die „Shape3D“Blattknoten in unserem Teilgraphen dar. Zur Erzeugung dieser Quader, werden das so eben erstellte Erscheinungsbild apBrett der Klasse Appearance sowie die geometrischen Daten zur Festlegung der Position und Größe dem Konstruktor übergeben. Das Erscheinungsbild und die Geometrie stellen die Knotenkomponenten für den Blattknoten dar. Die Schwerpunkte beider Quader, die als Objekte bxBrett und bxBrett90 der Klasse Box vorliegen, befinden sich nunmehr im Koordinatenursprung. Das Einzelbrett bxBrett verbleibt an seinem jetzigen Ort, wo hin gegen das Einzelbrett bxBrett90 durch eine Translation und anschließender Rotation an seinen Be- stimmungsort im 3D-Raum positioniert wird. Für die genannten Transformationen muss jeweils ein Objekt der Klasse Transform3D erstellt werden. Für die Rotation ist dies das Objekt t3dVerschiebeBrett. t3dRot90 Die rotX (float fRadiant) Rotation und wird für die Translation bestimmt, indem das die Objekt Methode mit dem Parameterwert Pi/2 (entspricht 90 Grad) aufge- rufen wird. Zur Bestimmung der Translation erfolgt ein Aufruf der Methode setTranslation (Vector3f vObj), (0.0f, -2.7f, -9.6f) welche als Parameter den Verschiebungsvektor für die Translationsmatrix MT erhält. Um dem „TransformGroup“-Knoten trGrBrett90 eine Tranformationskomponente zuzuteilen, müssen beide Transformationen miteinander verknüpft werden. Dies erfolgt durch die Anweisung: t3dRot90.mul (t3dVerschiebeBrett). Die Reihenfolge der Verknüpfung beider Transform3D-Objekte ist hierbei nicht unerheblich, Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 44 - wie nachfolgend erörtert wird. Zum besseren Verständnis der Transformation wird nachfolgendes Schaubild dargestellt. Abbildung 14: Transformationen des Quaders An Hand des Punktes P (0 / 0,4/ 10), welcher ein Kantenpunkt der Box bxBrett90 darstellt, werden die beiden Transformationen erklärt. Zuerst wird die Translation des Punktes P vorgenommen. Hierzu wird dieser mit der Transformationsmatrix MT (diese beinhaltet o. g. Verschiebungskoordinaten) multipliziert: MT (allgemein) 1 0 0 0 0 1 0 0 0 0 1 0 Bearbeitet von: André Och MT dx dy dz 1 1 0 0 0 0 1 0 0 0 0 1 0 0 -2,7 -9,6 1 x P X 0 0,4 10 1 = P’ = 0 -2,3 0,4 1 Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 45 - Das Ergebnis der Verschiebung ist das Quader-Objekt Box bxBrett90’ mit dem Kantenpunkt P’ (0 / -2,3 / 0,4). Im Anschluss hieran erfolgt die Rotation, wofür die Rotationsmatrix MR herangezogen wird. Der Punkt P’ wird multipliziert mit MR: MR (allgemein) 1 0 0 0 0 cos sin 0 0 -sin cos 0 x P’ X 0 -2,3 0,4 1 MR 0 0 0 1 1 0 0 0 0 0 1 0 0 -1 0 0 0 0 0 1 = = P’’ 0 -0,4 -2,3 1 Das Ergebnis der Rotation ist das Quader-Objekt Box bxBrett90’’ mit dem Kantenpunkt P’’ (0 / -0,4 / -2,3). Fazit beider Transformationen: Vereinfacht können beide Matrizen vor der Transformation miteinander multipliziert werden: MR x MT x P = P’’ Um auf den o. g. Aspekt bezüglich der Reihenfolge von Transformationen zurückzukommen, gilt folgende Regel: Matrizenmultiplikationen sind zwar assoziativ, aber nicht kommutativ, d. h. die Reihenfolge der Multiplikation von Matrizen, um eine zusammenhängende Transformation zu erzeugen, ist einzuhalten. Die Anweisung in der Klasse Spielbrett t3dRot90.mul (t3dVerschiebeBrett) t3dVerschiebeBrett.mul(t3dRot90) 9.5.2. kann deshalb nicht durch die Anweisung ausgetauscht werden. Die Spielstäbe Die sieben Spielstäbe, die für die Aufnahme der Bälle beider Spieler bestimmt sind, gehören zum Spielbrett und werden aus diesem Grund in der Klasse Spielbrett instanziiert. Die Programmklasse Staebe befindet sich in der Datei „Staebe.java“ und ist zuständig für die Erzeugung und Positionierung der geomet- Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 46 - rischen Objekte des entsprechenden Teilgraphs der Stäbe. Dieser wird in der Anlage 2 als blauer Teilbereich gekennzeichnet, dessen Wurzelknoten ein s. g. „Group“-Knoten ist. Mit diesem Knoten lassen sich verschiedene Objekte einer Szene gruppieren. Alle „Group“-Knoten besitzen nur einen Vater-Knoten und können beliebig viele Kind-Knoten haben. Diese können hinzugefügt, gelöscht oder gelesen werden. [Qxix] Die Klasse Staebe erbt deshalb von Group und wird in den „TransformGroup“-Knoten trGrBrett eingehängt (siehe Punkt 9.2 „Aufbau des Szenengraphen“), welcher sich in der Klasse Spielbrett befindet. Analog den Einzelbrettern wird eine Textur für die Stäbe verwendet. Das TexturObjekt texStaebe wird dem Erscheinungsbild apStaebe, welches dem Konstruktor der Stäbe übergeben wird, durch die Methode setTexture (Texture txObj) gesetzt. Im Konstruktor der Stäbe werden die geometrischen Objekte, die aus Zylindern gebildet werden, mit ihrem Erscheinungsbild erzeugt und entsprechend positioniert. Dazu wird das Feld vArrStabPos benutzt, in welchen die Raumkoordinaten der Zylinder-Schwerpunkte aufgenommen werden. Die X-Koordinaten der Stäbe sind öffentlich deklariert, weil sie später für die Erzeugung der Bälle wieder verwendet werden. Die Raumkoordinaten werden bei der Translation der Stäbe benötigt, für die analog zu den Einzelbrettern jeweils ein „TransformGroup“-Knoten eingesetzt wird. Dieser wird dem Gruppen-Knoten grStaebe angehängt. 9.6. Erzeugung und Kontrolle der Bälle Die Erzeugung der Bälle und die Bereitstellung deren Kontrolle erfolgt durch die Programmklasse Ballkontrolle, die sich in der Datei „Ballkontrolle.java“ befindet. Diese Klasse erbt von BranchGroup und wird in den „Locale“-Knoten eingehängt (siehe Punkt 9.2 „Aufbau des Szenengraphen“). In der Anlage 2 wird der entsprechende Szenenteilgraph als gelber Teilbereich gekennzeichnet, dessen Wurzelknoten die o. g. Klasse darstellt. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung 9.6.1. - 47 - Ballerzeugung Im Konstruktor der Klasse Ballkontrolle werden 42 Bälle für jeden Spieler erzeugt. Grund hierfür ist die Positionierung und Erzeugung der Bälle beim Programmstart. Es wird hierdurch wesentlich einfacher, Bälle zu setzen und aus der Spielszene zu entfernen, weil die Erscheinungsbilder und die Positionen der Bälle nicht dynamisch zur Laufzeit des Programms geändert bzw. gesetzt werden müssen. Zuerst muss das Erscheinungsbild für die Bälle festgelegt werden. Hierzu wird das Material-Objekt mat der Klasse Material erzeugt. Dieses ist ausschlaggebend für seine Reflexionseigenschaften. Sein Erscheinungsbild hängt im Wesentlichen davon ab, wie es auf das einfallende Licht reagiert. [Qxx] Nachfolgend werden die Parameter, die dem Konstruktor der Klasse Material übergeben werden, näher erörtert: Ambiente Farbe (Ambient Color): Farbe der Stellen des Objekts, die nur von dem ambienten Licht getroffen werden. Emittierende Farbe (Emissive Color): Farbe, die das Objekt selbst ausstrahlt Diffuse Farbe (Diffuse Color): Farbe, der allgemeinen Lichtreflektion Glanzlichtfarbe (Specular Color): Farbe, der Glanzpunkte am Objekt Glanzlichtstärke (Shininess): Wert für die Berechnung der Glanzpunkte [Qxxi] Abbildung 15: Reflektionsfarben eines Balls Die emittierende Farbe des dargestellten Balls ist schwarz und somit nicht sichtbar. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 48 - Die Materialobjekte der roten und rot leuchtenden Bälle des Spielers 1 sowie der gelben und gelb leuchtenden Bälle des Spielers 2 werden im Konstruktor erzeugt. Aus diesem Grund werden vier Objekte der Klasse Appearance (apRotSp1, apGewinnballSp1, apGelbSp2, apGewinnballSp2) benötigt, welchen die Material- Objekte mit der Methode setMaterial (Material matObj) zugeteilt werden. Um die Bälle an ihren Bestimmungsort transformieren zu können, wird analog zu den Stäben ein Feld mit Raumvektoren benutzt. Diese Vektoren werden in einer doppelt verschachtelten Schleife mit den X-Koordinaten der bereits erzeugten Stäbe und eigenen Y-Koordinaten (die Höhe der einzelnen Bälle an den Stäben) gesetzt. Um die Bälle während der Programmlaufzeit erscheinen und verschwinden zu lassen werden für jeden Spieler zwei „Switch“-Knoten eingesetzt, die als Objekte swSchalterSp1 und swSchalterSp2 der Klasse Switch zu instanziieren sind. Des- sen theoretischer Hintergrund kann aus dem Punkt 9.1 „Allgemeine Grundlagen“ nachgelesen werden. Dem Konstruktor der „Switch“-Objekte wird das Flag CHILD_MASK übergeben, um die Gruppen-Knoten über die Bit-Masken bsMaskeSp1 und bsMaskeSp2 anzusteuern. Dies wird erlaubt, indem mit der Methode setCapability (int iFlag) ALLOW_SWITCH_WRITE Ballkontrolle die entsprechenden Flags ALLOW_SWITCH_READ und gesetzt werden. Nachdem der „BranchGroup“-Knoten in den Szenengraph eingehängt ist, kann nun während der Lauf- zeit der „Switch“-Knoten verändert werden. Zur Aufnahme der Bälle werden für jeden Spieler ein Feld ( spKugelnSp1 [] und spKugelnSp2 []) jedes Ballobjekt definiert. Um die Translation der Bälle durchzuführen, wird für ein „TranformGroup“-Knoten mit einer „Transform3D“- Knotenkomponente bereitgestellt. Mit dem Feld vArrBallpos [], welches die Raumvektoren beinhaltet, werden dann die Positionen der Bälle im 3D-Raum festgelegt. Die Bälle werden anschließend mit dem für sie vorgesehenen Erscheinungsbild und ihren geometrischen Daten erzeugt. Hierbei gilt es, an dieser Stelle anzumerken, dass die Erlaubnis für die Veränderung des Erscheinungsbildes mit dem Flag ENABLE_APPEARANCE_MODIFY erteilt wird. Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 49 - Die erstellten Bälle, die jetzt als „Shape3D“-Blattknoten vorliegen, werden ihren entsprechenden „TransformGroup“-Knoten (trGrSp1 und trGrSp2) angehängt. Diese wiederum sind an den für den Spieler vorgesehen „Switch“-Gruppenknoten anzuhängen, welche dem „Group“-Knoten grBaelle als Kind-Knoten zugeordnet werden. Damit bei Spielbeginn keine Bälle in der „Vier Gewinnt“-Spielszene erscheinen, wird nach der clear (int index) Erzeugung des jeweiligen Balles die Methode der Klasse BitSet aufgerufen. Das Setzen der Bit-Maske er- folgt mittels der Methode setChildMask (BitSet bsMaske) der Klasse Switch. 9.6.2. Ballkontrolle Die Klasse Spielsteuerung hat die Kontrolle über die Bälle jedes Spielers. In der Klasse Ballkontrolle stehen hierzu folgende Methoden als Schnittstelle bereit: setzeNeuesSpiel (): Die Methode löscht die Bit-Masken beider Spieler und fügt sie den „Switch“Knoten neu hinzu, so dass die Bälle aus der Szene verschwinden. setzeBall (int iSpieler, int iPosition): Die Methode fügt einen Ball des Spielers iSpieler der Spielszene hinzu. Die Position iPosition entspricht dabei dem laufenden Index (0 <= iPosition <= 41) zur Veränderung der Bit-Maske, die hier neu gesetzt wird. setzeGewinnerBall (int iSpieler, int iPosition): Die Methode ändert das Erscheinungsbild eines bereits gesetzten Balles (für Spieler iSpieler) in einen leuchtenden Gewinnerball. Hierbei wird das Erscheinungsbild des Balles an Position iPosition im Feld der Bälle durch die Methode setAppearance (Appearance apObj) Bearbeitet von: André Och geändert. Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 50 - setzeGewinnerBallZurueck (int iSpieler, int iPosition): Analog zu o. g. Methode setzt diese das geänderte Erscheinungsbild des Gewinnerballes zurück in das Ursprungserscheinungsbild. 10. Implementierung des Clients Der Client als Programmteil des Computerspieles „Vier Gewinnt“ ist in der Programmklasse Client, welche sich in der Datei „Client.java“ befindet, implementiert. Die Klasse liefert den für den Aufbau, den Betrieb und den Abbau einer Netzwerkverbindung notwendigen Client. Dieser verwendet zur Kommunikation mit dem Server Instanzen der Klasse KommunikationsThread, die in der Datei „KommnunikationsThread.java“ implementiert ist. 10.1. Erstellung des Clients Zur Erzeugung eines Client-Objektes, die in der Klasse Spielsteuerung vorgenommen wird, muss das Java-Paket java.net.* importiert werden. Dem Konstruktor der Klasse werden dabei die Referenzen von Objekten der Klassen InetAddress und der Spielsteuerung übergeben. Das erstgenannte Objekt addrServer ist eine Beschreibung des Server-Endpunktes und wird für die Erstellung des Client-Sockets und der Datenverbindung benötigt. Dazu wird das Objekt sClient der Klasse Socket erzeugt, in dessen Konstruktor der Rechnername des Servers als String sowie der Portnummer PORT_SERVER übermittelt wird. Die Portnummer liegt als Integer in der Klasse Einstellungen vor. 10.2. Aufgaben des Clients Nachfolgend werden die Aufgaben des Client beschrieben: 10.2.1. Initiierung des Verbindungsaufbaus Die Voraussetzung für die Herstellung einer TCP-Verbindung ist die Existenz eines Servers im Netzwerk. Dieser wartet auf eine eintreffende Clientanfrage. Mit der Erstellung des Socket-Objektes initiiert der Client den Verbindungsaufbau. Die Verbindung kommt zu Stande, wenn der Client-Socket erfolgreich instanziiert wird. Des Weiteren werden die beiden Eingangs- und Ausgangsdatenströme als Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 51 - Objekte der Klassen ObjectOutputStream und ObjektInputStream zur Verfügung gestellt. Anschließend KommunikationsThread wird das Objekt thrEmpfaenger der Klasse erstellt. Hierbei werden ihm Referenzen der Objekte des Eingangsdatenstroms und der Spielsteuerung übergeben. Durch die Bereitstellung zweier Konstruktoren in der Klasse KommunikationsThread (siehe 6.2.2 „Nachrichtenaustausch“) kann dieser unterscheiden, ob er ein Thread für den Datenempfang oder für den Versand von Daten ist. Im Konstruktor des Clients wird somit ein Thread für den Datenempfang erzeugt, der durch den Aufruf der start ()-Methode aktiv wird. 10.2.2. Nachrichtenaustausch Für den Nachrichtenaustausch zwischen Client und Server werden serialisierte Objekte der Klasse Nachricht verwendet, welche aus diesem Grund die Schnittstelle Serializable implementiert (siehe Punkt 6.2.2 „Nachrichtenaustausch“). Datenempfang: Der Datenempfang des Client-Rechners wird analog zum Server-Rechner komplett durch den Thread der Klasse KommunikationsThread übernommen. Bei der zeitgleichen Implementierung des Servers und des Clients zeigte sich, dass beide die gleichen Methoden verwenden. Um Blockierungen der Hauptprozesse vom Client- und Server-Rechner beim Empfang von Daten zu vermeiden, wurde eigens hierfür o. g. Kommnunikations-Klasse eingeführt und von der Klasse Thread abgeleitet. Die genauere Vorgehensweise beim Datenempfang kann unter Punkt 6.2.2 nachgelesen werden. Datenversand: Die Spielsteuerung veranlasst die Versendung von Daten (siehe Punkt 5.5.3 „Bälle im Netzwerkspiel setzen“). Wird durch den Spieler am Client-Rechner ein Ball während eines Netzwerkspieles gesetzt, so muss mit Hilfe der Methode setzeBallBeiServer (int iStab) eine entsprechende Nachricht an den Server- Rechner versandt werden. Bei der Erzeugung eines serialisierten Nachrichten- Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 52 - Objektes wird dessen Konstruktor der Parameter iStab übergeben. Ferner wird ein Thread thrSchreiber zum Datenversand instanziiert, wobei dieser die Nachricht sowie eine Referenz auf den Ausgangsdatenstrom erhält. Schließlich wird der Thread gestartet. 10.3. Beenden des Clients Die bestehende TCP-Verbindung wird auf der Clientseite abgebrochen, in dem in der Spielsteuerung die Methode schliesseSocket () der Klasse Client ausgelöst wird. Hierzu wird der Client-Socket mit seiner Methode close () geschlossen. 11. Auslagerung der Einstellungen Alle wichtigen Einstellungen und Parameter werden in der Klasse Einstellungen, welche sich in der Datei „Einstellungen.java“ befindet, zentral zusammengefasst und dem Programm global zugänglich gemacht. Die Einstellungsklasse wird an keiner Stelle des Programms instanziiert. Sie hat daher keinen Konstruktor und ebenfalls keine Methoden. Es werden ausschließlich statische Daten, wie z. B. Konstanten, Pfade zu Dateien oder Materialfarben, erfasst, welche über das statische Objekt der Klasse zugänglich sind. 12. Installation und Ausführung des Programms Um das Computerspiel „Vier Gewinnt“ auf Windows oder auf Unix-Betriebssystemen ausführen zu können, muss das Java 2 Runtime Environment (Version 1.4.2 oder später) sowie die Java 3D Runtime for the JRE (OpenGL Version) (Version 1.3.1 oder später) installiert sein. Beide sind auf der Projekt-CD und können bezogen werden unter: J2RE für Windows und Unix-Betriebsysteme: http://java.sun.com/products/archive/j2se/1.4.2/index.html Java 3D: Für Windows und Solaris: http://java.sun.com/products/java-media/3D/download.html Bearbeitet von: André Och Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Projektbeschreibung - 53 - Für Linux: http://www.blackdown.org/java-linux/jdk1.2-status/java-3d-status.html 12.1. Installation und Ausführen unter Windows Die Installation unter Windows gestaltet sich relativ einfach. Es müssen nacheinander die Dateien j2re-1_4_2-windows-i586.exe und java3d-1_3_1-windows-i586opengl-rt.exe ausgeführt und den entsprechenden Installationsanweisungen ge- folgt werden. Anschließend ist das Verzeichnis CD-Laufwerk:\4G_Programm\ auf die Festplatte zu kopieren und die darin enthaltene Batch-Datei VierGewinnt.bat auszuführen. 12.2. Installation und Ausführen unter Linux SuSE Zuerst wird ein Verzeichnis angelegt, in welches das J2RE installiert werden soll. In dieses wird die Datei j2re-1_4_2-linux-i586.bin hinein kopiert und mit dem Befehl ./j2re-1_4_2-linux-i586.bin stallationsanweisungen ist in der Konsole ausgeführt. Den entsprechenden In- Folge java3d-re-1.3.1-linux-i386.bin zu leisten. Anschließen wird die Datei in das Verzeichnis ./j2re1.4.2/ kopiert und der Befehl /bin/bash ./java3d-re-1.3.1-linux-i386.bin ausgeführt. Wiederum ist den Installationsanweisungen Folge zu leisten. Zum Starten des Spieles „Vier Gewinnt“ muss aus dem Programmverzeichnis 4G_Programm auf den Rechner kopieren) der Befehl viergewinnt.VierGewinnt (von der Projekt-CD /pfad_zu_j2re/j2re1.4.2/bin/java in der Konsole ausgeführt werden. 12.3. Ausführen in den Rechnerräumen C002 bis C005 in der Fachhochschule Fulda Auf den Windows-Rechnern wird im Programmverzeichnis 4G_Programm\ folgender Befehl ausgeführt: C:\jsdk1.4.2_02\bin\java viergewinnt.VierGewinnt Auf den Solaris-Rechnern wird im Programmverzeichnis 4G_Programm\ folgender Befehl ausgeführt: java viergewinnt.VierGewinnt Gegebenenfalls sollte bei Problemen bei den Solaris-Rechnern der Befehl more /opt/global/news/hinweis_4 Bearbeitet von: André Och für weitere Hinweise ausgeführt werden. Matr.-Nr. 164 836 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Anhang und Anlagen - 54 - 13. Anhang 13.1. Abbildungsverzeichnis Abbildung 1: Programmmenü des Computerspiels "Vier Gewinnt" ........................... 5 Abbildung 2: Setzen des Balles................................................................................. 5 Abbildung 3: Meldung in der Statuszeile ................................................................... 6 Abbildung 4: Spielende durch Sieg ........................................................................... 6 Abbildung 5: IP-Adresse des Servers angeben ......................................................... 7 Abbildung 6: Auswahl des Spielbeginners ................................................................ 7 Abbildung 7: Grobes Schaubild der Schnittstellen .................................................. 11 Abbildung 8: Darstellung des Arrays für die Aufnahme der Bälle ............................ 13 Abbildung 9: Ermittlung des laufenden Index .......................................................... 15 Abbildung 10: Die diagonale Laufrichtung ............................................................... 17 Abbildung 11: Anordnung der Panels im Hauptfenster ........................................... 32 Abbildung 12: Aufbau eines Szenengraphen .......................................................... 35 Abbildung 13: Richtung des direktionalen Lichtes ................................................... 41 Abbildung 14: Transformationen des Quaders ........................................................ 44 Abbildung 15: Reflektionsfarben eines Balls ........................................................... 47 13.2. Inhalt der Projekt CD Die mitgelieferte Projekt-CD beinhaltet folgende Daten: Verzeichnis 4G_Programm\: Enthält das ausführbare Programm „Vier Gewinnt“ Verzeichnis Dokumentation\: Enthält diese Dokumentation und die dafür verwendeten Dateien Verzeichnis Java3D_install\: Enthält die zur Ausführung des Programms notwendigen Installationsdateien von Sun, um Java3D-Programme starten zu können. Wir weisen auf die Lizenzvereinbarungen unter o. g. Links hin ! Verzeichnis Präsentation\: Enthält die am 22.01.2004 vorzuführende Präsentation Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Anhang und Anlagen - 55 - Verzeichnis Projektmusik\: Enthält die Projektmusik, die den Prüfer beim Korrigieren dieser Dokumentation aufmuntern soll Verzeichnis Quellcode\: Enthält den Java-Quellcode des Programms „Vier Gewinnt“ Verzeichnis Quellen\: Enthält die Quellen, die für das Projekt verwendet wurden 13.3. Quellenverzeichnis Q i: Lutz Emmel; „CliXX Java3D – Der Grundkurs; Verlag Harri Deutsch; ISBN 3-8171-1637-3; 2000, Seite 14 (Bild von der CD zu dem Buch). Das Bild ist auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Quelle 1\szenengraph.gif Qii: Buch wie in Quelle Q1, Seite 13 Qiii: Buch wie in Quelle Q1, Seite 15 Qiv: Buch wie in Quelle Q1, Seite 15 Qv: Link: abgespeichert. http://www.rz.rwth-aachen.de/vr/teaching/lectures/ws01/java3d_seminar.pdf, Christoph Ender; Seminar Computergrafik / TU BS SS 99; Seite 7 (Die Datei ist auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Quelle 5\ java3d_seminar.pdf abgespeichert. Qvi Link wie in Quelle Q5, Seite 15 Qvii: Link wie in Quelle Q5, Seite 12 Qviii: Link: http://www.htw-dresden.de/~stripgen/Java3D/folien/J3DV5.pdf, von Prof. Simone Strippgen, 2002, Seite 6 (Die Datei ist auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Quelle 8\J3DV5.pdf abgespeichert. Um sie zu Öffnen wird ein Passwort benötigt, welches in der Datei Passwort.txt im selben Verzeichnis mitgeliefert wird.) Qix: Link wie in Quelle Q5, Seite 13 Qx: Link wie in Quelle Q5, Seite 18 Qxi: Link wie in Quelle Q5, Seite 18 Qxii: Link wie in Quelle Q5, Seite 18 Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Anhang und Anlagen Qxiii: Link wie in Quelle Q5, Seite 18 Qxiv: Link wie in Quelle Q5, Seite 18 Qxv: Link wie Quelle Q8, jedoch Datei J3DV7.pdf, Seite 6 Qxvi: Link wie Quelle Q8, jedoch Datei J3DV7.pdf, Seite 4 - 56 - Qxvii: Link wie Quelle Q8, jedoch Datei J3DV12.pdf, Seite 15 Qxviii: Link wie Quelle Q8, jedoch Datei J3DV12.pdf, Seite 17 Qxix: Link wie Quelle Q8, jedoch Datei J3DV4.pdf, Seite 2 Qxx: Teilskriptum zur Lehrveranstaltung „Grafik-Programmierung“ im WS 2003/2004 von Prof. Dr. W. Heinzel, Fachhochschule Fulda, FB AI, Seite A1.4-15 Qxxi: Link wie Quelle Q8, jedoch Datei J3DV12.pdf, Seite 35 Als weitere Studiergrundlagen dienten folgende Quellen: Guido Grüger, „Handbuch der Java-Programmierung“, Addison-Wesley, ISBN 3-8273-1949-8, 2002 Lutz Emmel, „CliXX, Java 3D – Der Grundkurs“, Verlag Harri Deutsch, ISBN 3-8171-1637-3, 2002 Link: http://medialab.it.fhtesslingen.de/cfapps/doku_archiv/dateien/ Java3DSpecification.pdf, Sun microsystems, „The Java 3DTM API Specification“, 2000, (Die Datei ist auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Allgemeine Quellen\ Java3DSpecification.pdf abgespeichert. Link: http://www.hta-bi.bfh.ch/~swc/DemoJ3D/Mill3D/ D. Dällenbach, M. Trachsel, „Projekt Mill 3D“, 1999, (Die Dateien sind auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Allgemeine Quellen\Mill3d abgespeichert. Link: http://www.informatik.htw-dresden.de/~stripgen/Java3D/inhalt.htm, Strippgen, Simone, Prof. Dr. rer. nat., "Aufbau der Lehrveranstaltung Java 3D Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Anhang und Anlagen - 57 - Programmierung“, 2002, (Die Dateien sind auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Quelle 8\ abgespeichert. Um sie zu Öffnen wird ein Passwort benötigt, welches in der Datei Passwort.txt im selben Verzeichnis mitgeliefert wird.). Link: http://www.c-lab.de/java/Java3D-Tutorial/ Sun microsystems, „Getting Started with the Java 3DTM API“, 1999, (Die Dateien sind auf der Projekt-CD unter dem Pfad CD-Laufwerk:\Quellen\Allgemeine Quellen\Getting Started Java3D\ abgespeichert. Für das Computerspiel „Vier Gewinnt“ wurden urheberrechtlich geschützte Musik sowie Geräusche verwendet, deren Interpreten nachfolgend genannt werden: Die „Vier Gewinnt“-Musik: Interpret: Die Fantastischen Vier Erschienen: 1992 Plattenverlag: “columbia / sony music entertainment (germany)” Geräusch „Ball setzen“: Interpret: Bill Gates Musik-Quelle: Betriebssystem Windows XP, Geräusch „Ballon-Tips“ zu finden unter: /Windows/Media/Windows XP-Sprechblase.wav Geräusch „Feld löschen“: Interpret: Bill Gates Musik-Quelle: Betriebssystem Windows XP, Geräusch „Papierkorb leeren“ zu finden unter: /Windows/Media/Windows XP-Papierkorb.wav Projekt „Vier Gewinnt“, Systemprogrammierung WS 03/04 Anhang und Anlagen 14. Anlagen Folgende Anlagen zu dieser Dokumentation werden umseitig mitgeliefert: Anlage 1: Klassendiagramm, Projekt „Vier Gewinnt“ Anlage 2: Java3D-Szenengraph, Projekt „Vier Gewinnt“ Anlage 3: Der Quellcode zum Programm „Vier Gewinnt“ - 58 -