Designproblem: "Wenn man nicht weiß wer man ist und wer noch da ist"



  • 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?!


Anmelden zum Antworten