Tutorials/Demo-Netzwerk-Spiel: Unterschied zwischen den Versionen
Mike (Diskussion | Beiträge) (→Ein Protokoll zur Koordination der Netzwerk-Kommunikation) |
Mike (Diskussion | Beiträge) (→Ein Protokoll zur Koordination der Netzwerk-Kommunikation) |
||
(25 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
== Demo-Netzwerk-Spiel == | == Demo-Netzwerk-Spiel == | ||
− | In diesem | + | In diesem Beispiel sollst du ein tieferes Verständnis für eine Client-Server-Kommunikation im Rahmen eines einfachen Demo-Netzwerk-Spiels erhalten. Zwei Spieler verbinden sich mit einem Server, anschließend können sie gegeneinander / miteinander spielen. |
− | * | + | [[Datei:Screenshot_demo-netzwerk_spiel.png]] |
− | * | + | |
− | * | + | Jeder Spieler sendet hierzu seine Änderungs-Wünsche an den Server, dieser leitet sie dann an alle Spieler weiter. Erst die Nachrichten des Servers führen bei den Clients zu sichtbaren Änderungen. So wird sicher gestellt, dass der eigene Spieler nicht flinker auf Eingaben reagiert als der gegnerische Spieler. Hier werden nun folgende Aspekte genauer erklärt: |
+ | |||
+ | * Der Aufbau und die Aufgaben des Servers | ||
+ | * Der Aufbau und die Aufgaben des Clients | ||
+ | * Das Protokoll zur Koordination der Netzwerk-Kommunikation | ||
* Zusammenspiel aller benötigten Komponenten | * Zusammenspiel aller benötigten Komponenten | ||
− | === | + | === Klassen-Diagramm === |
− | Du siehst hier das Klassen-Diagramm des Demo-Netzwerk-Spiels. Alle rot gefärbten Klassen wirst du selbst erstellen. Alle schwarz gefärbten Klassen stellt dir die ''Engine Alpha'' zur Verfügung. | + | Du siehst hier das '''Klassen-Diagramm''' des Demo-Netzwerk-Spiels. Alle rot gefärbten Klassen wirst du selbst erstellen. Alle schwarz gefärbten Klassen stellt dir die ''Engine Alpha'' zur Verfügung. |
[[Datei:klassendiagramm_demo_netzwerk_spiel.png]] | [[Datei:klassendiagramm_demo_netzwerk_spiel.png]] | ||
− | + | === Überblick aller benötigten Komponenten === | |
− | * Die Klasse '''MyGameServer''' realisiert die Server-Instanz des Spiels. Bei ihr müssen sich die Clients anmelden bevor das Spiel beginnen kann. An diese Instanz sendet jeder Spieler später seine Änderungs-Wünsche. Der Server wird diese Wünsche dann an alle angemeldeten Clients verbreiten. Die Klasse ''MyGameServer'' hat ein Referenz-Attribut vom Typ {{Doc|ea/Server}} (aus der Engine Alpha). Hierüber werden die Nachrichten an die Clients gesendet. Um auch Nachrichten empfangen zu können, implementiert die Klasse ''MyGameServer'' das Interface {{Doc|ea/Empfaenger}} (der Engine Alpha), welches | + | * Die '''Spielfigur''' kannst du prinzipiell gestalten, wie du willst. Hier handelt es sich der Einfachheit halber um einen {{Doc|ea/Kreis}} in dem der Name des Spielers als {{Doc|ea/Text}} steht. Die Klasse ''Spielfigur'' erbt von der Klasse {{Doc|ea/Knoten}} um die Einzelteile (Text und Kreis) zu einer Gesamtheit zu gruppieren. Dadurch kann später die Spielfigur als ein Ganzes in die Wurzel des Grafik-Systems eingehängt werden. Auch ihre Bewegung kann so mit nur einem Befehl realisiert werden. |
+ | |||
+ | * Die Klasse '''MyGameServer''' realisiert die Server-Instanz des Spiels. Bei ihr müssen sich die Clients anmelden bevor das Spiel beginnen kann. An diese Instanz sendet jeder Spieler später seine Änderungs-Wünsche. Der Server wird diese Wünsche dann an alle angemeldeten Clients verbreiten. Die Klasse ''MyGameServer'' hat ein Referenz-Attribut vom Typ {{Doc|ea/Server}} (aus der Engine Alpha). Hierüber werden die Nachrichten an die Clients gesendet. Um auch Nachrichten empfangen zu können, implementiert die Klasse ''MyGameServer'' das Interface {{Doc|ea/Empfaenger}} (der Engine Alpha), welches einige Methoden vorschreibt zum Empfangen von Nachrichten. Jede dieser Methoden wird später automatisch aufgerufen werden, sobald von der Client-Seite eine Nachricht eingeht. | ||
* Die Klasse '''MyGame''' sorgt für die grafische Darstellung bei jedem der Clients. Deshalb muss sie von der (Engine Alpha) Klasse '{{Doc|ea/Game}} erben. Sie verfügt über zwei Referenz-Attribute vom Typ ''Spielfigur'' um die eigene Spielfigur und die des Gegners verwalten zu können. Beide Referenzen werden in einem Array verwaltet. Es gibt noch ein drittes Referenz-Attribut der Klasse ''MyNetworkClient''. An dieses ''MyNetworkClient''-Objekt werden die Änderungswünsche (Tastatur-Ereignisse) übergeben und von diesem werden auch die Antworten des Servers (Zustands-Änderungen der Spielfiguren) empfangen. Von der Klasse ''MyGame'' muss jeder Spieler eine Instanz erzeugen. (Vorher muss eine ''MyGameServer''-Instanz erzeugt worden sein.) | * Die Klasse '''MyGame''' sorgt für die grafische Darstellung bei jedem der Clients. Deshalb muss sie von der (Engine Alpha) Klasse '{{Doc|ea/Game}} erben. Sie verfügt über zwei Referenz-Attribute vom Typ ''Spielfigur'' um die eigene Spielfigur und die des Gegners verwalten zu können. Beide Referenzen werden in einem Array verwaltet. Es gibt noch ein drittes Referenz-Attribut der Klasse ''MyNetworkClient''. An dieses ''MyNetworkClient''-Objekt werden die Änderungswünsche (Tastatur-Ereignisse) übergeben und von diesem werden auch die Antworten des Servers (Zustands-Änderungen der Spielfiguren) empfangen. Von der Klasse ''MyGame'' muss jeder Spieler eine Instanz erzeugen. (Vorher muss eine ''MyGameServer''-Instanz erzeugt worden sein.) | ||
* Die Klasse '''MyNetworkClient''' ist auf der Client-Seite für die Kommunikation mit dem Server verantwortlich. Sie erbt von der (Engine Alpha) Klasse {{Doc|ea/Client}} und verfügt dadurch über Methoden zum Senden von Nachrichten zum Server. Die ebenfalls von der Klasse {{Doc|ea/Game}} geerbten (abstrakten) Methoden zum Empfangen von Nachrichten vom Server müssen mit konkreten Inhalten überschreiben werden. Die Klasse ''MyNetworkClient'' hat noch ein Referenz-Attribut vom Typ ''MyGame''. Das ist das Grafik-Fenser, an das die Befehle bzgl. Zustands-Änderungen der Spielfiguren weiter geleitet wird. | * Die Klasse '''MyNetworkClient''' ist auf der Client-Seite für die Kommunikation mit dem Server verantwortlich. Sie erbt von der (Engine Alpha) Klasse {{Doc|ea/Client}} und verfügt dadurch über Methoden zum Senden von Nachrichten zum Server. Die ebenfalls von der Klasse {{Doc|ea/Game}} geerbten (abstrakten) Methoden zum Empfangen von Nachrichten vom Server müssen mit konkreten Inhalten überschreiben werden. Die Klasse ''MyNetworkClient'' hat noch ein Referenz-Attribut vom Typ ''MyGame''. Das ist das Grafik-Fenser, an das die Befehle bzgl. Zustands-Änderungen der Spielfiguren weiter geleitet wird. | ||
+ | |||
+ | == Details zur Funktion des Spiels == | ||
=== Aufgaben des Servers === | === Aufgaben des Servers === | ||
− | Der Server- | + | Der Server-Dinst wird zunächst auf einem beliebigen Rechner im Netzwerk gestartet. Von nun an lauscht er auf einem festgelgten Port (oberhlab 1024) auf Verbindungs-Anfragen der Clients. Nach erfolgreicher Verbindung mit den Spiel-Clients nimmt er jeden Wunsch auf Zustands-Änderungen entgegen und verteilt sie an alle Clients, damit diese dann quasi zeitgleich die Änderungen im Grafik-Fenster umsetzen können. Hierzu ist auf Server-Seite ein '''Server-Protokoll''' und auf Client-Seite ein '''Client-Protokoll''' nötig, die beide weiter unten genauer erläutert werden. |
+ | |||
+ | '''Zustands-Übergangs-Diagramm''' des '''Server'''s: | ||
+ | |||
+ | [[Datei:zustandsdiagramm_server.png]] | ||
=== Aufgaben des Clients === | === Aufgaben des Clients === | ||
Zeile 36: | Zeile 48: | ||
* Bei unserem Demo-Netzwerk-Spiel gibt es nur drei verschiedene Befehle, die an den Server gesendet werden dürfen. | * Bei unserem Demo-Netzwerk-Spiel gibt es nur drei verschiedene Befehle, die an den Server gesendet werden dürfen. | ||
− | + | ** <code>anmelden:''name''</code> | |
− | + | ** <code>bewegen:''index'':''dx'':''dy''</code> | |
− | + | ** <code>farbwechsel:''index'':''farbe''</code> | |
* Auf Client-Seite sieht das Protokoll ebenfalls drei Befehle vor: | * Auf Client-Seite sieht das Protokoll ebenfalls drei Befehle vor: | ||
− | + | ** <code>neu:''name'':''index'':''x'':''y''</code> | |
− | + | ** <code>bewegen:''index'':''dx'':''dy''</code> | |
− | + | ** <code>farbwechsel:''index'':''farbe''</code> | |
+ | |||
+ | Wei man leidcht erkennt, sind zwei der Befehle auf beiden Seiten identisch. Den dritten Befehl gibt es jeweils nur auf einer Seite. Dabei stellen die Doppelpunkte Trennzeichen zwischen den einzelnen Bestandteilen eines Befehls dar. Der erste Teil jedes Befehls gibt die Art des Befehls an, die kursiv geschriebenen weiteren Teile sind (verpflichtende) Parameter, für die in jedem konkreten Fall entsprechende Werte eingesetzt werden müssen. ''name'' ist der Name des Spielers. ''index'' ist eine für jeden Client eindeutige Zahl (Index im Array) zu deren Unterscheidung. ''x'' und ''y'' sind die Start-Koordinaten eines Spielers. ''dx'' und ''dy'' sind die Schrittweiten der Bewegung. | ||
+ | |||
+ | '''Sequenz-Diagramm''' zum '''Anmelden''' der Clients beim Server: | ||
+ | |||
+ | [[Datei:sequenzdiagramm_anmelden.png]] | ||
+ | |||
+ | '''Sequenz-Diagramm''' zum '''Bewegen''' eines Spielers: | ||
+ | |||
+ | [[Datei:sequenzdiagramm_bewegen.png]] | ||
+ | |||
+ | ''Das '''Sequenz-Diagramm''' zum '''Ändern der Farbe''' eines Spielers ist analog aufgebaut.'' | ||
+ | |||
+ | == Demo-Projekt == | ||
+ | <div class="hinweisProbleme"> | ||
+ | Hier findest du das Beispiel-Projekt: | ||
+ | * [https://github.com/engine-alpha/demo-netzwerkgame/archive/master.zip Ein einfaches (sinnloses) Demo-Netzwerk-Spiel (mit Broadcast-Server)] | ||
+ | </div> | ||
+ | |||
+ | |||
+ | == Erweiterungs-Möglichkeiten == | ||
+ | |||
+ | Das Spiel hat bisher keinen Sinn. Man kann nur die Spieler bewegen und deren Farbe ändern. Selbst ein sauberes Beenden des Spiels ist noch nicht implementiert. | ||
+ | |||
+ | * Erweitere das Protokoll um einen '''vierten Befehl zum Abmelden'''. <br />''Sendet ein Client dem Server eine Nachricht zum Abmelden, so wird diese vom Server an beide Clients weiter gereicht. Daraufhin beendet der Server die Verbindung zu beiden Clients. (Die Clients werden daraufhin automatisch ihre Verbindung zum Server schließen.'' | ||
− | + | * '''weitere Features''' wie z.B. eine Kollisions-Kontrolle solltest du dem Server überlassen. <br />''Würdest du sie in den Clients implementieren, so würde die Kollision zwei Mal festgestellt und dem Server übermittelt werden. Auch weitere (automatisch bewegte) Spielfiguren musst du vom Server steuern lassen ...'' |
Aktuelle Version vom 26. Februar 2015, 19:17 Uhr
Inhaltsverzeichnis
Demo-Netzwerk-Spiel
In diesem Beispiel sollst du ein tieferes Verständnis für eine Client-Server-Kommunikation im Rahmen eines einfachen Demo-Netzwerk-Spiels erhalten. Zwei Spieler verbinden sich mit einem Server, anschließend können sie gegeneinander / miteinander spielen.
Jeder Spieler sendet hierzu seine Änderungs-Wünsche an den Server, dieser leitet sie dann an alle Spieler weiter. Erst die Nachrichten des Servers führen bei den Clients zu sichtbaren Änderungen. So wird sicher gestellt, dass der eigene Spieler nicht flinker auf Eingaben reagiert als der gegnerische Spieler. Hier werden nun folgende Aspekte genauer erklärt:
- Der Aufbau und die Aufgaben des Servers
- Der Aufbau und die Aufgaben des Clients
- Das Protokoll zur Koordination der Netzwerk-Kommunikation
- Zusammenspiel aller benötigten Komponenten
Klassen-Diagramm
Du siehst hier das Klassen-Diagramm des Demo-Netzwerk-Spiels. Alle rot gefärbten Klassen wirst du selbst erstellen. Alle schwarz gefärbten Klassen stellt dir die Engine Alpha zur Verfügung.
Überblick aller benötigten Komponenten
- Die Spielfigur kannst du prinzipiell gestalten, wie du willst. Hier handelt es sich der Einfachheit halber um einen
Kreis
in dem der Name des Spielers alsText
steht. Die Klasse Spielfigur erbt von der KlasseKnoten
um die Einzelteile (Text und Kreis) zu einer Gesamtheit zu gruppieren. Dadurch kann später die Spielfigur als ein Ganzes in die Wurzel des Grafik-Systems eingehängt werden. Auch ihre Bewegung kann so mit nur einem Befehl realisiert werden.
- Die Klasse MyGameServer realisiert die Server-Instanz des Spiels. Bei ihr müssen sich die Clients anmelden bevor das Spiel beginnen kann. An diese Instanz sendet jeder Spieler später seine Änderungs-Wünsche. Der Server wird diese Wünsche dann an alle angemeldeten Clients verbreiten. Die Klasse MyGameServer hat ein Referenz-Attribut vom Typ
Server
(aus der Engine Alpha). Hierüber werden die Nachrichten an die Clients gesendet. Um auch Nachrichten empfangen zu können, implementiert die Klasse MyGameServer das InterfaceEmpfaenger
(der Engine Alpha), welches einige Methoden vorschreibt zum Empfangen von Nachrichten. Jede dieser Methoden wird später automatisch aufgerufen werden, sobald von der Client-Seite eine Nachricht eingeht.
- Die Klasse MyGame sorgt für die grafische Darstellung bei jedem der Clients. Deshalb muss sie von der (Engine Alpha) Klasse '
Game
erben. Sie verfügt über zwei Referenz-Attribute vom Typ Spielfigur um die eigene Spielfigur und die des Gegners verwalten zu können. Beide Referenzen werden in einem Array verwaltet. Es gibt noch ein drittes Referenz-Attribut der Klasse MyNetworkClient. An dieses MyNetworkClient-Objekt werden die Änderungswünsche (Tastatur-Ereignisse) übergeben und von diesem werden auch die Antworten des Servers (Zustands-Änderungen der Spielfiguren) empfangen. Von der Klasse MyGame muss jeder Spieler eine Instanz erzeugen. (Vorher muss eine MyGameServer-Instanz erzeugt worden sein.)
- Die Klasse MyNetworkClient ist auf der Client-Seite für die Kommunikation mit dem Server verantwortlich. Sie erbt von der (Engine Alpha) Klasse
Client
und verfügt dadurch über Methoden zum Senden von Nachrichten zum Server. Die ebenfalls von der KlasseGame
geerbten (abstrakten) Methoden zum Empfangen von Nachrichten vom Server müssen mit konkreten Inhalten überschreiben werden. Die Klasse MyNetworkClient hat noch ein Referenz-Attribut vom Typ MyGame. Das ist das Grafik-Fenser, an das die Befehle bzgl. Zustands-Änderungen der Spielfiguren weiter geleitet wird.
Details zur Funktion des Spiels
Aufgaben des Servers
Der Server-Dinst wird zunächst auf einem beliebigen Rechner im Netzwerk gestartet. Von nun an lauscht er auf einem festgelgten Port (oberhlab 1024) auf Verbindungs-Anfragen der Clients. Nach erfolgreicher Verbindung mit den Spiel-Clients nimmt er jeden Wunsch auf Zustands-Änderungen entgegen und verteilt sie an alle Clients, damit diese dann quasi zeitgleich die Änderungen im Grafik-Fenster umsetzen können. Hierzu ist auf Server-Seite ein Server-Protokoll und auf Client-Seite ein Client-Protokoll nötig, die beide weiter unten genauer erläutert werden.
Zustands-Übergangs-Diagramm des Servers:
Aufgaben des Clients
Ein Client muss sich im Netzwerk zuerst mit dem Server verbinden. Hierzu muss der Client die IP-Adresse (z.B. 192.168.1.100) und den Port (z.B. 1234) des Servers kennen. Nach erfolgreicher Verbindung kann der Client Nachrichten an den Serer schicken. Diese Nachrichten müssen einer vorher festgelegten Struktur folgen - dem Server-Protokoll. Jede Nachricht an den Server wird von diesem an alle Clients weiter geleitet, damit jederzeit jeder Client über dieselbe Informtaion verfügt. Auch die Nachrichten vom Server an die Clients müssen einer festgelegten Struktur folgen - dem Client-Protokoll. Diese neu ankommenden Informationen werden auf Client-Seite dann in grafische Änderungen (gemäß dem Client-Protokoll) umgesetzt. Beide Protokolle werden im nächsten Punkt genauer erläutert.
Ein Protokoll zur Koordination der Netzwerk-Kommunikation
Client und Server können nicht beliebige Nachrichten austauschen. Erst wenn beide Seiten dieselbe Sprache sprechen, kann eine sinnvolle Kommunikation erfolgen. Ein Protokoll legt den genauen Aufbau der erlaubten Befehle fest. Es kann ein Protokoll auf Server-Seite und ein anderes auf Client-Seite geben.
- Bei unserem Demo-Netzwerk-Spiel gibt es nur drei verschiedene Befehle, die an den Server gesendet werden dürfen.
anmelden:name
bewegen:index:dx:dy
farbwechsel:index:farbe
- Auf Client-Seite sieht das Protokoll ebenfalls drei Befehle vor:
neu:name:index:x:y
bewegen:index:dx:dy
farbwechsel:index:farbe
Wei man leidcht erkennt, sind zwei der Befehle auf beiden Seiten identisch. Den dritten Befehl gibt es jeweils nur auf einer Seite. Dabei stellen die Doppelpunkte Trennzeichen zwischen den einzelnen Bestandteilen eines Befehls dar. Der erste Teil jedes Befehls gibt die Art des Befehls an, die kursiv geschriebenen weiteren Teile sind (verpflichtende) Parameter, für die in jedem konkreten Fall entsprechende Werte eingesetzt werden müssen. name ist der Name des Spielers. index ist eine für jeden Client eindeutige Zahl (Index im Array) zu deren Unterscheidung. x und y sind die Start-Koordinaten eines Spielers. dx und dy sind die Schrittweiten der Bewegung.
Sequenz-Diagramm zum Anmelden der Clients beim Server:
Sequenz-Diagramm zum Bewegen eines Spielers:
Das Sequenz-Diagramm zum Ändern der Farbe eines Spielers ist analog aufgebaut.
Demo-Projekt
Hier findest du das Beispiel-Projekt:
Erweiterungs-Möglichkeiten
Das Spiel hat bisher keinen Sinn. Man kann nur die Spieler bewegen und deren Farbe ändern. Selbst ein sauberes Beenden des Spiels ist noch nicht implementiert.
- Erweitere das Protokoll um einen vierten Befehl zum Abmelden.
Sendet ein Client dem Server eine Nachricht zum Abmelden, so wird diese vom Server an beide Clients weiter gereicht. Daraufhin beendet der Server die Verbindung zu beiden Clients. (Die Clients werden daraufhin automatisch ihre Verbindung zum Server schließen.
- weitere Features wie z.B. eine Kollisions-Kontrolle solltest du dem Server überlassen.
Würdest du sie in den Clients implementieren, so würde die Kollision zwei Mal festgestellt und dem Server übermittelt werden. Auch weitere (automatisch bewegte) Spielfiguren musst du vom Server steuern lassen ...