Labyrinth über MazeGameServer visualisieren

Diskutiere Labyrinth über MazeGameServer visualisieren im Softwareentwicklung Bereich.
P

Plauzi92

Was willst du Mir damit sagen, warum brauche ich eine Instanz vom see Klasse Field oder was meinst du Mir "Typ Field"? Und wie Gebe ich jetzt genau einem Feld die Position not?
Du hast doch eine Klasse Field oder nicht? Aus dieser werden die Instanzen (also im Prinzip deine einzelnen Mauern und Wege) erstellt. Jede dieser Mauern/Wege hat einen X Wert und einen Y Wert woraus sich die genau Position in dem Labyrinth ergibt. Position (0|0) wäre demnach oben links in der Ecke.
Außerdem hast du den FieldType. Das kann ein String, oder ein Integer ( 0 für Weg, 1 für Mauer) oder auch irgendwas anderes sein, dass dir gefällt und Sinn macht.

Wenn du also ein neues Field erstellst, kannst du durch den Konstruktor direkt die Parameter mitgeben.

Die Klasse Field sähe dann so aus:

Code:
public class Field {
private int PositionX, PositionY;
private String Type;

public Field(int PositionX, int PositionY, String Type) {    // <- Das ist der Konstruktor
        this.PositionX = PositionX;
        this.PositionY = PositionY;
        this.Type = Type;
    }
}
Und beim erstellen eines neuen Fields an der Position (20|20) vom Typ WALL gibst du das direkt mit:

Code:
Field neuesField = new Field(20,20,"WALL");
 
J

JustNobody

Also ein paar Punkte:

a) Ich denke, dass es schon wichtig ist, dass sich mehrere Personen beteiligen, denn ein Einzelner kann immer mal keine Zeit haben zum antworten.

b) Plauzi92 hat einfach eine Art Optimierung gemacht. So der Server richtig funktioniert, werden alle Wege durch Mauern abgegrenzt sein. Diese "Unknown" Felder dürften den Client also nicht interessieren. Daher optimiert er so, dass er einfach nur die Mauern speichert. Kann man so machen, aber die Frage ist, ob man damit die Erwartungshaltung bezüglich der Aufgabe erfüllt. In einem realen Projekt sollte die Analyse so sein, dass man klar festlegt, was gebraucht wird. Wenn da 3 Typen von Feld definiert sind, dann würde ich diese auch so umsetzen. Hintergrund ist, dass bei agilen Arbeiten das halt erst ein Punkt ist und es kommen noch weitere Entwicklungsschritte hinterher.
Oder anders gesagt: Dann hätte ich diese Optimierung auch schon direkt beim Server erwartet....

c) Generell führen viele Wege zum Ziel. Du kannst den Konstruktor durchaus so schreiben, wie Du ihn zuletzt geschrieben hast. Worauf ich hinaus wollte, war:
Du wirst beim Client das Labyrinth abfragen und es zurück bekommen. Die Rückmeldung vom Server verwendest Du, um z.B. ein 2d Array von Field zu füllen. Zum Füllen rufst Du also für jede Position des 2d Arrays ein Konstruktor auf. Jeder Aufruf wird also eine neue leere Liste für die Baits übergeben.
Aber das funktioniert natürlich:
felder[x][y] = new Field(getFieldType(scannedType), new ArrayList<BaitType>());

Das wäre dann die Nutzung Deines Konstruktors. Aber dann stellst Du fest:
1) getFieldType(scannedType) kann von der Funktionalität in Field einfließen oder in FieldType. Das nennt sich dann Refactoring. Kann man machen, aber zur Not ist so Code erst einmal an anderer Stelle ... alles prinzipiell ok. Das Thema kann man nach Erstellung einer Lösung angehen.
2) Du rufst den Konstruktor immer mit new ArrayList<BaitType>() auf. Dann kannst Du auf diesen Parameter verzichten und im Konstruktor statt dessen diesen Code schreiben. Dann hättest Du etwas wie:
Java:
private Field(FieldType fieldType) {
        this.fieldType = fieldType;
        this.baittypes = new ArrayList<BaitType>();
    }
Aber auch hier gilt: Kann man machen, aber das wäre auch ein Punkt, den man nach einer ersten Lösung machen kann (so man so gewisse Dinge nicht sieht).

Um so Refactorings ggf. zu vermeiden kann man Funktionalität sozusagen "Top - Down" entwickeln. Das ist generell üblich. In der Regel findet dies aber schon bei der Auflistung der Tasks statt: Was wird wofür gebraucht? Daraus entstehen dann die klaren Aufgaben, was z.B. für "Field" gebraucht wird. Oder man macht es einfach Top/Down bei der Entwicklung. Was brauchst Du denn von Field? Du startest oben bei der Implementierung nachdem Du einen groben Plan hast. Wie der Konstruktor genau aussieht, ist Dir erst einmal egal. Lass ihn zur Not erst einmal weg.
Wenn Du dann die ersten Field Instanzen erzeugen musst, dann siehst Du, was Du hast: Das kann dann also ein String sein mit der Darstellung des Feldes. Und dann gibt es halt einen Konstruktor, der einfach nur so einen String entgegen nimmt.... So vermeidest Du, unnötig Zeit zu verschwenden.
Aber ganz wichtig: Der grobe Aufbau und wo welche Daten gespeichert werden: Das musst Du von Anfang an festlegen. Ohne so ein Design kommst Du nicht weit. Aber das hast Du und da würde ich jetzt nicht zu viel Zeit rein stecken und das ggf. "on the fly" erweitern in den Details.

Ach ja: Der neue Punkt "Position des Feldes":
Nimm das Beispiel Bücherregal: Ein Buch steht im Bücherregal. Wie in der Bücherei: Platz B46 ist von diesem Buch.
Jetzt kann man das natürlich auch im Buch vermerken. Aber muss man das? Das wäre wichtig, wenn man die Position ständig benötigen würde: Du hast das Buch heraus genommen und nun muss man es zurück stellen. Dann braucht man das.
Aber wenn Du nun Bücher in ein regal stellst: Dann hast Du natürlich auch die Bücher an speziellen Positionen. Über die Position kannst Du auf die Bücher zugreifen. Im Buch muss die Position nicht stehen.

Wenn Du Blätter auf den Schreibtisch legst: Du notierst ja nicht die Position auf den Blättern. Aber wenn Du die Blätter brauchst: Kein Thema: Die Blätter liegen da und da auf dem Schreibtisch. -> zugriff klappt auch ohne dass der Ort vermerkt wird.

So sehe ich das hier auch. Wenn Du z.B. ein 2d Array mit Feldern hast, dann greifst Du darüber auf das jeweilige Feld zu. Aber den Feldern ist es egal, an welcher Position sie sind. Es sind einfach Feld-Instanzen und der Ort ist durch die Referenzierung im 2d Array festgelegt.
 
J

JustNobody

Du hast doch eine Klasse Field oder nicht? Aus dieser werden die Instanzen (also im Prinzip deine einzelnen Mauern und Wege) erstellt. Jede dieser Mauern/Wege hat einen X Wert und einen Y Wert woraus sich die genau Position in dem Labyrinth ergibt. Position (0|0) wäre demnach oben links in der Ecke.
Außerdem hast du den FieldType. Das kann ein String, oder ein Integer ( 0 für Weg, 1 für Mauer) oder auch irgendwas anderes sein, dass dir gefällt und Sinn macht.

Wenn du also ein neues Field erstellst, kannst du durch den Konstruktor direkt die Parameter mitgeben.

Die Klasse Field sähe dann so aus:

Code:
public class Field {
private int PositionX, PositionY;
private String Type;

public Field(int PositionX, int PositionY, String Type) {    // <- Das ist der Konstruktor
        this.PositionX = PositionX;
        this.PositionY = PositionY;
        this.Type = Type;
    }
}
Und beim erstellen eines neuen Fields an der Position (20|20) vom Typ WALL gibst du das direkt mit:

Code:
Field neuesField = new Field(20,20,"WALL");
Sorry, von dem Aufbau halte ich so erst einmal nichts. Du hast doch ein klaren 2d Aufbau fester Größe. Desweiteren sollte man bei einem Objektorientierten Ansatz bleiben und sich von den Native Types lösen wo es nur geht. Und dieses Lösen könnte man über mehrere Wege machen:

Ein erster Schritt ist erst einmal, die Literale in Konstanten umzuwandeln. Dann hast Du statt "WALL" halt irgend eine Konstante a.la. Field.TYPE_WALL oder so.
Dannkommt aber sofort der zweite Refactoring-Schritt:Du hast mehrere Konstanten, die zusammen gehören und Du hast eine Variable, die nur bestimmte Werte annehmen kann: Also kommt direkt das Enum.

Dann muss Code an die richtige Stelle. Der Typ eines Feldes sollte also gewisse Dinge wissen wie
- kann ein Spieler auf das Feld? (So es nur vom Typ abhängt)
- wie wird es vom Server dargestellt?

Dann ist klar, wo genau dieser Code steht. Er ist an einer klar definierten Stelle und man hat Verantwortung nicht künstlich in anderen Klassen abgelegt.

Das ist aber nur meine Sicht. Deine Lösung wird auch funktionieren. Aber wie gesagt: Mir sagt die so nicht zu und sobald man es weiter ausbaut wird es schnell unnötig komplex und damit unwartbar.
 
mrBrown

mrBrown

Ist an der Position (X/Y) ein Objekt Field mit dem Typ "WALL"? -> Ja? -> Nicht setzen
Ist an der Position (X/Y) ein Objekt Wall? ->Ja? -> Nicht setzen

Macht doch absolut keinen Unterschied, nur dass man sich bei letzterer Variante den FieldType spart.
Natürlich macht das einen Unterscheid, das sind völlig unterschiedliche Designs:

1598386379081.png1598386545455.png1598386489786.png

Möglich sind X verschiedene Varianten, aber Unterschiede macht das in jedem Fall.


Den Konstruktor bräuchtest du doch auch ohne FieldType damit du der Instanz vom Typ Field die Position direkt mitgeben kannst.
Allerdings muss ein Feld eigentlich nie seine Position wissen. Wenn es die weiß, hat man die Information doppelt gespeichert, was zu Problemen führen kann und oft auch führt.
 
P

Plauzi92

Allerdings muss ein Feld eigentlich nie seine Position wissen. Wenn es die weiß, hat man die Information doppelt gespeichert, was zu Problemen führen kann und oft auch führt.
Stimme ich zu. Habe die Positionen zwar da rein geschrieben aber im Endeffekt nie genutzt. Tatsächlich reicht das 2D-Array
 
J

jono

Wenn Du dann die ersten Field Instanzen erzeugen musst, dann siehst Du, was Du hast: Das kann dann also ein String sein mit der Darstellung des Feldes. Und dann gibt es halt einen Konstruktor, der einfach nur so einen String entgegen nimmt....
1.
Ein String zur Darstellung des Feldes? Ein Feld wird doch durch eine array position lokalisiert und hat einen FieldType vom Typ Enumeration, verstehe ich jetzt nicht ganz.
2.
Wie erzeuge ich den Field Instanzen, bzw. wo sollen die erzeugt werden? Was ich auch nicht verstehe, was konkret an einem Beispiel von mir aus, heißt es, dass ein Konstruktor entgegen nimmt?
3.
Essentiell noch mal für mich wäre zu klären, welche Aufgabe der Konstruktor jetzt konkret erfüllen soll? Ein Konstruktor dient ja eigentlich nichts anderem als der Erzeugung von Objekten. Wäre super wenn mir das jemand evtl. an einem Fallbeispiel erklären kann. Also die Informationen, die der Server dem Client übergibt bei der Anforderung des MAZE, sind ja im Endeffekt Objekte, aber wie bringe ich das jetzt in Einklang mit dem Konstruktor, weil wenn ich mich richtig entsinne, dann war der Konstruktor doch mit dem Erhalt der Informationen in Zusammenhang gebracht worden?
 
J

jono

Ach ja: Der neue Punkt "Position des Feldes":
Nimm das Beispiel Bücherregal: Ein Buch steht im Bücherregal. Wie in der Bücherei: Platz B46 ist von diesem Buch.
Jetzt kann man das natürlich auch im Buch vermerken. Aber muss man das? Das wäre wichtig, wenn man die Position ständig benötigen würde: Du hast das Buch heraus genommen und nun muss man es zurück stellen. Dann braucht man das.
Aber wenn Du nun Bücher in ein regal stellst: Dann hast Du natürlich auch die Bücher an speziellen Positionen. Über die Position kannst Du auf die Bücher zugreifen. Im Buch muss die Position nicht stehen.

Wenn Du Blätter auf den Schreibtisch legst: Du notierst ja nicht die Position auf den Blättern. Aber wenn Du die Blätter brauchst: Kein Thema: Die Blätter liegen da und da auf dem Schreibtisch. -> zugriff klappt auch ohne dass der Ort vermerkt wird.

So sehe ich das hier auch. Wenn Du z.B. ein 2d Array mit Feldern hast, dann greifst Du darüber auf das jeweilige Feld zu. Aber den Feldern ist es egal, an welcher Position sie sind. Es sind einfach Feld-Instanzen und der Ort ist durch die Referenzierung im 2d Array festgelegt.
Okay, danke gutes Beispiel!
 
J

JustNobody

Zu 1: schau dir an, wie das Spiel abläuft. Der Client fragt den Server nach dem Maze. Der Server schickt dann das Maze: was genau sendet der Server zurück? Aus dem, was der Server zurück sendet musst du ja deine Daten aufbauen....

Zu 2. Du musst dir den Ablauf genau ansehen. Die Kommunikation zwischen Client und Server ist ja genau spezifiziert. Wie läuft denn dann so ein Spiel ab? Gev das einmal in Ruhe durch um eine Vorstellung davon zu bekommen, wann der Client was macht und was für Daten er verarbeiten muss.

Zu 3. Der Konstruktor dient der Initialisierung von neuen Instanzen. Für das Erzeugen ist das new verantwortlich. Wenn mit new eine neue Instanz einer Klasse erzeugt wird, wird der angegebene Konstruktor zur Initialisierung aufgerufen.
Dabei können Daten für die neue Instanz übergeben werden.
 
J

jono

Zu 1: schau dir an, wie das Spiel abläuft. Der Client fragt den Server nach dem Maze. Der Server schickt dann das Maze: was genau sendet der Server zurück? Aus dem, was der Server zurück sendet musst du ja deine Daten aufbauen....
Ja, der Server sendet String commands die der CommandHandler in GameStatusModel updatet.


Zu 2. Du musst dir den Ablauf genau ansehen. Die Kommunikation zwischen Client und Server ist ja genau spezifiziert. Wie läuft denn dann so ein Spiel ab? Geh das einmal in Ruhe durch um eine Vorstellung davon zu bekommen, wann der Client was macht und was für Daten er verarbeiten muss.
Warum den Ablauf ansehen, den habe ich ja schon genau verstanden! Mir geht es jetzt genau um den Konstruktor, ich bekomme Informationen vom CommandHandler aufgrund eines ServerBefehls. Dieser aktualisiert Daten in GameStatusModel, sei es Field oder Player...
Wenn es Field ist, werden z.B. Baits oder fieldTypes aktualisiert, heißt es werden neue Instanzen erzeugt oder wie ??? Ja im Prinzip schon aber wie werden die erzeugt, ich kenne das so dass ich z.B. Instanzen einer Klasse in einer anderen Klasse erzeuge bzw. in einer Main-Klasse. Ich kenne das nicht so wie das hier gemacht werden soll. Kannst du mir da konkreter behilflich sein?

Zu 3. Der Konstruktor dient der Initialisierung von neuen Instanzen. Für das Erzeugen ist das new verantwortlich. Wenn mit new eine neue Instanz einer Klasse erzeugt wird, wird der angegebene Konstruktor zur Initialisierung aufgerufen.
Dabei können Daten für die neue Instanz übergeben werden.
Ja, das ist mir alles bewusst, wichtig ist mir wirklich zu wissen wie der Konstruktor jetzt ganz konkret seine Aufgabe erfüllen soll..

Noch eine Frage:
Java:
private FieldType fieldType;
    private List<BaitType> baittypes = new ArrayList<BaitType>();
Eine Instanzvariable fieldType brauche ich dann jetzt nicht mehr ? Weil das wurde ja abgetan von euch, es hieß erst diese darf nicht null sein, dann habe ich sie ungleich null gemacht und das war dann auch falsch gewesen.
 
J

jono

1598449978667.png
Und wie baue ich diese jetzt noch dazu ein, ist sehr abstrakt hier formuliert.
 
J

jono

1. Wie implementiere ich Properties die einen Zustand speichern,
2. Was ist da wieder genau mit Zustand gemeint, statische Variablen und enum werte auch oder?
 
J

jono

Also wie ich die Properties in GameStatus Model implementiere ist klar, aber wie setze ich das in JavaFX um, wobei ich denke, dass ich die Frage nochmal stelle wenn ich das FX-Subsystem angefangen habe
 
J

JustNobody

Sorry, aber ich bezweifle, dass Du das wirklich überblickst.

Irgendwo wirst Du hoffentlich die Felder des Labyrinths speichern wollen. Und diese Stelle musst Du aktualisieren, wenn Du die Daten vom Server bekommst, die ja so aussehen sollen:
Code:
MAZE;20;10
--------------------
-##################-
-#................#-
-#.###.#.###.##.#.#-
-#...###..#..#..#.#-
-#.#.........#..#.#-
-#.#########.#.##.#-
-#................#-
-##################-
--------------------
Also musst Du aus diesem Text irgendwie die Daten zusammen bekommen. Das könnte z.B. sein, dass Du ein 2d Array von Field erstellst mit der entsprechenden Größe also z.B. hier [20][10].
Und dazu musst Du dann die Zeichen auswerten. Aus dem '-' Zeichen soll ein Field werden vom Typ UNKNOWN. Aus dem'.' Zeichen ein Field vom Typ PATH und aus dem '#' ein Field vom Typ WALL (Oder wie die Typen bei Dir auch immer heißen - habe ich jetzt nicht nachgeschlagen!)

Also brauchst Du ganz offensichtlich Code, der aus einem Zeichen ein Field erstellt. Das könnte man über einen Konstruktor machen. Aber das kann man auch gerne anders machen - das ist mir auch relativ egal. Mach es so, wie Du es machen möchtest, aber MACH EINFACH. Setz Dich dran und schau, wie Du das erstellt bekommen kannst. Und wenn Du alles in eine zentrale Klasse packst die dann direkt auf den anderen Klassen agiert. Das kann man später anpassen (Refactoring). Nur mach die Logik! Dann siehst Du auch, was Du brauchst.

Und auf die Frage, ob man den FieldTyp braucht, da habe ich jetzt einfach keinen Ansatz mehr. Wir haben da nun wirklich lang und breit drüber gesprochen. Du hast den Typ auf einen festen Wert gesetzt. Das ist Quatsch, denn alle Felder sind ja nicht vom gleichen Typ! Und natürlich muss der Typ gesetzt werden, denn ein Feld ist entweder vom Typ UNKNOWN, PATH oder WALL. Also hast Du eine Variable, die gesetzt sein muss: Dann setz diese doch im Konstruktor. Und da es unterschiedliche Felder mit unterschiedlichen Typen gibt: Übergib etwas, so dass Du den Typ setzen kannst.

Das kann also einfach nur der FieldType sein, den du direkt übergibst. Oder Du übergibst das Zeichen und dann sucht der Konstruktor raus, was für ein Typ das ist. Das kann z.B. in einem switch passieren wenn Du das so machen möchtest.

Was die Properties angeht: Nutz einfach die entsprechenden Property Klassen. Also erstell eine Instanz von StringProperty und schon kannst Du ein Control an diese Property binden. Aber da einfach mal ein paar Beispiele zu JavaFX ansehen. Das ist ja nun ein Gebiet, wo es im Internet sehr viele Seiten zu gibt....
 
J

jono

Und da es unterschiedliche Felder mit unterschiedlichen Typen gibt: Übergib etwas, so dass Du den Typ setzen kannst.
Was soll das heißen? Wie übergebe ich etwas einem Konstruktor, die Begriffe die du da verwendest geben mir kein Aufschluss darüber?Was soll ich übergeben, was heißt ein Typ "setzen"?

Du hast den Typ auf einen festen Wert gesetzt. Das ist Quatsch, denn alle Felder sind ja nicht vom gleichen Typ! Und natürlich muss der Typ gesetzt werden, denn ein Feld ist entweder vom Typ UNKNOWN, PATH oder WALL. Also hast Du eine Variable, die gesetzt sein muss: Dann setz diese doch im Konstruktor.
Ja ich habe doch eine Variable namens vom Typ FieldType in den Konstruktor gesetzt?
 
Zuletzt bearbeitet:
J

jono

Also brauchst Du ganz offensichtlich Code, der aus einem Zeichen ein Field erstellt. Das könnte man über einen Konstruktor machen.
Wie macht man das mit einem Konstruktor, ich kenne nur die einfache Instanziierung von Variablen einer Klasse. Mit new wird ein Konstruktor aufgerufen. Aber wie erstelle ich dann mit einem Konstruktor aus einem Zeichen ein Field. Das ist mir einfach völlig fremd
 
J

JustNobody

Wenn eine Methode Parameter hat und dann wird die Methode aufgerufen: Dann wird da umgangssprachlich von "übergeben" gesprochen.
Also Du hast eine Methode test, die einen int Parameter hat. Dann kannst Du test aufrufen und z.B. 5 übergeben: test(5);

Einer Variable einen Wert zuweisen: Das wäre umgangssprachlich das setzen. "Typ" entsprach hier einfach deiner FieldType Variablen.

Und Du kannst einen Konstruktor schreiben wie jede Methode. Da kann also mehr drin sein als nur einfache Zuweisungen. Also sowas wie:
Java:
public Field(final char character) {
  switch (character) {
      case '.': fieldType = FieldType.WAY; break;
      case '#': fieldType = FieldType.WALL; break;
      case '-': fieldType = FieldType.UNKNOWN; break;
      default: throw new IllegalArgumentException("Character " + character + " is not valid!");
  }
}
Oder
Java:
public Field(final char character) {
  fieldType = FieldType.of(character);
}
Und in FieldType hast Du dann eine Methode
Code:
public static FieldType of(final char character) { ... }
die diese Umwandlung enthält. Und das entweder mit einem switch wie oben gezeigt oder ggf. wie schon einmal früher exemplarisch gezeigt mit einer for each Schleife und Prüfen eines Wertes, der jedem enum Eintrag zugewiesen wurde. Das suche ich jetzt aber nicht raus und Du kannsteinfach bei einem switch bleiben und gut ist es ...
 
J

jono

@JustNobody
1. Wozu brauche ich Dann die Methoden in FieldType?

2. Nun möchte ich das Command-Pattern implementieren.
Wie Gehe ich dabei genauer vor?
Ich muss erstmal eine Klasse Command mit der execute() Methoden schreiben, die Dann von den jeweiligen Servernachrichten wie z.B. die MAZE (MAZE wird Dann eine Befehlsklasse public class Maze) implementieren wird. Als pro Servernachricht eine Befehlsklasse, die die jeweiligen Änderungen in GameStatusModel vornehmen?
 
J

jono

?
diese Umwandlung enthält. Und das entweder mit einem switch wie oben gezeigt oder ggf. wie schon einmal früher exemplarisch gezeigt mit einer for each Schleife und Prüfen eines Wertes, der jedem enum
Warum Schreibst du es Dann erst in den Konstruktor von Field und Dann sagst du die Umwandlung soll in die Methoden von FieldType?
 
J

JustNobody

Ich habe einfach mehrere Möglichkeiten aufgezählt, wie es implementiert werden könnte.

Aber ich habe schon gesagt Spätestens in #173 ("Das könnte man über einen Konstruktor machen. Aber das kann man auch gerne anders machen - das ist mir auch relativ egal. Mach es so, wie Du es machen möchtest, aber MACH EINFACH. Setz Dich dran und schau, wie Du das erstellt bekommen kannst. Und wenn Du alles in eine zentrale Klasse packst die dann direkt auf den anderen Klassen agiert. Das kann man später anpassen (Refactoring). Nur mach die Logik!")

Das erste war einfach eine 08/15 Lösung für Dich. Einfach zu verstehen und vielleicht hast Du diese ja verstanden. Das was folgt, ist ein Refactoring - also eine Art Verbesserung, denn Code, der den FieldType betrifft sollte eigentlich auch da drin zu finden sein. Field sollte keine Entscheidungen treffen, die FieldType zustehen, also auch nicht, welches Zeichen denn nun welchem FieldType entspricht. Aber das ist nebensächlich. Bau nur einfach eine Lösung, die Du verstehst.
 
J

jono

Das wäre dann soweit geklärt.
Jetzt möchte ich den CommandHandler implementieren, d.h. die jeweiligen eingehenden Servernachrichten in ein Befehlsobjekt konvertieren. Dann sollen verschiedene Befehlsklassenn pro Servernachricht erstellt werden, um GameStatusModel über Änderungen zu informieren. Das Ganze stellt ja das Command-Pattern dar.
Wie genau erstellt man jetzt die Befehlsobjekte die auf die jeweilige Befehlsklasse verweisen sollen?
Die jeweiligen Servernachrichten sind ja I'm CSV Format gegeben. Diese müssen eingelesen werden als String-Datentyp.
Meine Frage:
Wie genau gehe ich jetzt vor, wie verknüpfe ich die Blickrichtung (z.B. die 2. Position eines CSV-Datensatzes wie bei der PPOS Servernachricht in der exam-task.pdf) mit einer Befehlsklasse, welche die Blickrichtung ändern kann?
In der Befehlsklasse selbst wird die Blickrichtung geändert, nachdem die Nachricht ausgelesen würde und auf die jeweiligen Befehlsklassen verweist...
Kann mir da jemand konkret behilflich sein und mir gute Tipps gehen ? 🙂
 
Thema: 

Labyrinth über MazeGameServer visualisieren

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben