Designproblem: "Wenn man nicht weiß wer man ist und wer noch da ist"
-
Hi Leute!
Ich habe ein kleines Designproblemchen...
Folgendes: Ich habe eine Klasse Objekt von der alle möglichen Objekte sich ableiten, z. B. Spielfiguren, Gegner, Gegenstände und so weiter und sofort.
Diese ganzen Objekte speichere ich dann in einer Managerklasse in einer STL-Liste, von wo sie aus aktuallisiert und gezeichnet werden. Geht auch erste Sahne.
Ein Problem ist jedoch jetzt die Tastaturbelegung der Spieler, da die sich je nach Anzahl der Spieler ändert.
Folgende Tastaturbelegungen habe ich:
Spieleranzahl: 1
Spieler 1: Pfeiltasten.Spieleranzahl: 2
Spieler 1: WASD-Tasten.
Spieler 2: Pfeiltasten.Spieleranzahl: 3
Spieler 1: WASD-Tasten.
Spieler 2: IJKL-Tasten.
Spieler 3: Pfeiltasten.Mein Problem ist jetzt einfach ausgedrückt: Ein Spieler der Klasse "player" weiß nicht wieviele Spieler es gibt und welcher Spieler er gerade ist, wodurch ich nicht die Tastenbelegungen in der update-Methode setzen kann

Ich hab mal etwas Code für euch zur Verdeutlichung:
// Klasse für Objekte. class object { public object () { } public ~object () { } public virtual bool update (double delta) = 0; public virtual bool draw (double delta) = 0; } // Klasse für Spieler. class player : public object { public player () : object () { } public bool update (double delta) { if (nur ein spieler) { // Tastenbelegung PFEILTASTEN } else if (zwei spieler) { if (spieler eins) { // Tastenbelegung: WASD } else // if (spieler zwei) { // Tastenbelegung: PFEILTASTEN } } else if (drei spieler) { if (spieler eins) { // Tastenbelegung: WASD } else if (spieler zwei) { // Tastenbelegung: IJKL } else // if (spieler drei) { // Tastenbelegung: PFEILTASTEN } } return (true); } public bool draw (double delta) { return (true); } } // Klasse für Gegner. class enemy : public object { // [...] } // [...] // Liste mit Objekten. std::list<object> m_objects; // [...] // Aktuallisieren aller Objekte for (std::list<object>::iterator it = m_objects.begin (); it != m_objects.end (); ++it) it->update (delta);Ich hoffe ihr könnt mir bei diesem Problem aus der Patsche helfen

Viele liebe Grüße!
C++'ler
-
Der Spieler weiß nicht, wer er ist - das Spiel schon. Also solltest du beim Anlegen der Spieler festlegen, welche Tasten er verwenden soll (z.B. als Ctor-Parameter).
-
Ich wuerde den Spielercharacter (also das Maenneken in der Spielwelt) von seiner Steuerung trennen. Denn deine Klasse Object scheint mir nur eine Oberklasse fuer die Zeichenbaren Objekte zu sein, was mit der Art der Steuerung recht wenig zu tun hat.
class object; //... class character : public object { virtual bool draw(); public: //steuerung void go_left(); void go_right(); void go_ahead(); void go_back(); }; class UserInterface { character* mychar; public: UserInterface(TastenSatz& t); void tastendruck() { if (/*linke taste gedrueckt*/) mychar->go_left(); //etc. } };Das macht es auch einfacher, spaeter Computerspieler einzufuehren. Die wurden dann genauso go_left() etc. aufrufen. Schliesslich sollte es der gezeichneten Spielfigur herzlich egal sein ob sie jetzt per Tastatur, Gamepad oder KI gesteuert wird. Dem Interface den Tastensatz zu uebergeben hat den Vorteil, dass du auch Benutzerdefinierte Tastenbelegungen uebergeben kannst.
-
hmn beide Ansätze sind recht gut
Hmn, aber welches soll man nehmen? 
-
Beides zusammen
Das Spiel legt beim Start nmensch+nKI character-Objekte an und übergibt davon einige an die UserInterface-Objekte, denen es auch gleich "ihre" Bewegungstasten zuweist.
-
Hi,
Danke ihr Beiden! Hab es nun mal so implementiert und das geht erste Sahne

Jedoch habe ich nun ein weiteres Problemchen: Gegenstände.
Wenn ein Spieler z. B. mit einem Objekt kollidiert, kann er da nicht durch gehen. Habe ich auch über die update-Methode implementiert. (Jedes Objekt hat ja eine Rechteck-Struktur.)
Der Spieler darf aber auch Gegenstände aufheben, diese wiederum sind auch von der Klasse "object" abgeleitet - nur darf er da durch gehen.
Die Frage ist jetzt: Wie weiß ich jetzt anhand der objekt-Liste welches Objekt ein Item ist, ein Spieler oder sogar ein Baum, Haus, Gegner o.ä.? Je nach Objekt soll ja etwas anderes passieren.
Habt ihr dazu noch eine Idee?

-
Nachtag: Ich hab mir z. B. überlegt in "object" noch eine Art "Typ" zu hinterlegen vom Datentyp "string".
Dachte da an sowas, was ich auf cppreference.com gefunden habe:
#define to_string(s) # s class object { protected std::string type_; public object () : type_ (to_string (object) {} };Bin mir da aber absolut unsicher

-
mit den zusätzlichen Methoden go_left, etc, wird es unmöglich alle Objekte gleich mit einer Iteration zu updaten. Ich würde in Die welt ein eigenes Modul einbauen, was sich um die Steuerung kümmert. So können sich die Player objekte die Informationen, in welche richtung sie sich bewegen sollen selber abhohlen, ohne dass sie jemand speziell ansprechen muss.
class World{ void update(){ //alles updaten(); } void draw(){ //alles darstellen } updateInput(){ //die Gesamte eingabe verarbeiten, und in eine //privaten Datenstruktur der Klasse World abspeichern } void getplayermove(Input *si, int playernumber){ //hier ist die öffentliche schnittstelle zu den eingabedaten. //es werden aber keine rohen eingabe Daten vergeben, sondern //Eindeutige bewegungsangaben, wie z.b. Bewegungsrichtung, //oder befehl zum schießen. } };Ich hab jetzt nicht alles dargestellt, soll nur so grob angeben, wie es später aussehen könnte (die klasse oder auch enum Input fehlt). So könnte man dann später auch beliebig viele weitere Spieler hinzufügen, ohne dass irgendetwas an der updatemethode geändert werden soll.
hab das so aber bisher noch nie implementiert (werd ich aber glaub ich mal versuchen.)
-
hast du mal java programmeirt?
-
BorisDieKlinge schrieb:
hast du mal java programmeirt?
C#
-
C++'ler schrieb:
Die Frage ist jetzt: Wie weiß ich jetzt anhand der objekt-Liste welches Objekt ein Item ist, ein Spieler oder sogar ein Baum, Haus, Gegner o.ä.? Je nach Objekt soll ja etwas anderes passieren.
Die allgemeine Lösung wäre eine Multimethode collide. Schau dir mal diesen Artikel an: http://www.c-plusplus.net/forum/viewtopic-var-p-is-1130360.html
C++'ler schrieb:
Nachtag: Ich hab mir z. B. überlegt in "object" noch eine Art "Typ" zu hinterlegen vom Datentyp "string".
Das ist Unfug. Der Typ ist bekannt genug.
-
sieht man;)

-
.filmor schrieb:
C++'ler schrieb:
Die Frage ist jetzt: Wie weiß ich jetzt anhand der objekt-Liste welches Objekt ein Item ist, ein Spieler oder sogar ein Baum, Haus, Gegner o.ä.? Je nach Objekt soll ja etwas anderes passieren.
Die allgemeine Lösung wäre eine Multimethode collide. Schau dir mal diesen Artikel an: http://www.c-plusplus.net/forum/viewtopic-var-p-is-1130360.html
C++'ler schrieb:
Nachtag: Ich hab mir z. B. überlegt in "object" noch eine Art "Typ" zu hinterlegen vom Datentyp "string".
Das ist Unfug. Der Typ ist bekannt genug.
der artikel ist absolut unverständlich.
Vorallem was mich daran nervt sind so sätze wie:
"man sollte ..., was aber simpel ist."Wenns doch so simpel ist, warum baut er es nicht ein? Denkt der wir können jetzt alle Mutlimethoden?
Sorry, kein guter Artikel. muss man echt mal sagen...
-
Krux schrieb:
mit den zusätzlichen Methoden go_left, etc, wird es unmöglich alle Objekte gleich mit einer Iteration zu updaten.
Eh?
class player_ui : public key_listener , public controller { public: virtual void update( float dt ) { if (change_direction_) { (player_->*move_func_)(); change_direction_ = false; } } virtual void on_key_event( int key_code ) { // set appropriate move_func_ change_direction_ = true; } }; class player : public game_object { public: virtual void update( float dt ) { update_controllers(dt); // ... } void go_*() { // set move_vector_ } };
-
Hab mir grade auch mal den artikel durchgelesen, also wenn sowas kommt:
"Klar ist, dass go in konstanter Zeit einen Fehler meldet oder die richtige Funktion aufruft. Auch klar ist, dass der Dispatcher mit Vererbung nicht richtig funktioniert. "und man diesen Satz mehrfach in abgewandelter Form in diesen Artikel ließt fragt man sich: Läuft da überhaupt etwas?!