variable Spielsteuerung



  • Hallo zusammen,
    hab ein Spiel programmiert bei dem man in alle Richtungen laufen kann. Momentan funktioniert die Steuerung über die Pfeil-Tasten (in einer switch-Anweisung)

    Ich möchte jetzt aber das der Spieler selbst bestimmen kann, mit welchen Tasten welche Richtung gesteuert werden soll!

    Bei case-Anweisungen kann ich ja nicht mit Variablen arbeiten, oder?
    Hat jemand ne Idee wie ich das verwirklichen könnte???

    Schon mal vielen Dank im Voraus!



  • Du könntest die Tasten in einem Array unterbringen und dann über ihren Index ansprechen:

    char arrows[4] = {75/*Links*/,72/*Hoch*/,77/*Rechts*/,80/*Runter*/}
    //wenn Bedarf besteht, die Werte überschreiben:
    
    switch(memchr(arrows,input,4)-arrows)
    {
      case 0: //links
      case 1: //hoch
      case 2: //rechts
      case 3: //runter
      default://unbekannte Taste
    }
    


  • Standard-Alternativ-Vorschlag:

    class foo
    {
    private:
      typedef char key_t;
      typedef void (foo::*callback_t)();
      typedef std::map<key_t, callback_t> key_binding;
    
    public:
      foo()
      {
        key_bindings_['w'] = &foo::whatever;
        key_bindings_['s'] = &foo::something;
        key_bindings_['S'] = &foo::something;
      }
    
      void handle_key_press( key_t key )
      {
        key_binding::iterator kit = key_bindings_.find(key);
        if (kit != key_bindings_.end()) {
          (this->*kit->second)();
        }
      }
    
    private:
      void whatever()  { std::cout << "whatever!\n"; }
      void something() { std::cout << "something!\n"; }
    
      key_binding key_bindings_;
    };
    
    int main()
    {
      foo bar;
      bar.handle_key_press('w');
      bar.handle_key_press('s');
      bar.handle_key_press('S');
    }
    


  • @CStoll:
    Danke für den Hinweis werds mal so versuchen.

    @finix:
    Ebenfalls Danke! Kann damit leider aber nichts anfangen. Versteh bei dem Quellcode nur Bahnhof! 😞



  • bpfitzner schrieb:

    @finix:
    Ebenfalls Danke! Kann damit leider aber nichts anfangen. Versteh bei dem Quellcode nur Bahnhof! 😞

    Ist im Prinzip ziemlich simpel. Den Code den du vermutlich direkt in den switch-cases stehen hast packst du in Methoden.
    Zur Laufzeit suchst du dir dann die dem Argument entsprechende Methode raus und führst sie aus.

    class spiel
    {
    private:
      typedef char key_t; // Typ fuer "case-Konstante"
      typedef void (spiel::*callback_t)(); // Typ fuer "case-Code"
      typedef std::map<key_t, callback_t> key_binding; // Unser "switch"-Typ
    
    public:
      spiel()
      {
        key_bindings_['w'] = &spiel::spieler_hoch;   // case 'w': spieler_hoch();
        key_bindings_['a'] = &spiel::spieler_links;  // case 'a': spieler_links();
        key_bindings_['s'] = &spiel::spieler_runter; // case 's': spieler_runter();
        key_bindings_['d'] = &spiel::spieler_rechts; // case 'd': spieler_rechts();
      }
    
      void handle_key_press( key_t key )
      {
        // unser "switch(key)":
        // Suche in key_bindings_ nach dem Schluessel 'key'
        key_binding::iterator kit = key_bindings_.find(key);
        // Falls gefunden...
        if (kit != key_bindings_.end()) {
          // ... fuehre die Methode aus
          (this->*kit->second)();
        }
        // Falls nicht, koennte hier im else-Zweig der
        // "default:-case" stehen/aufgerufen werden
      }
    
    private:
      void spieler_hoch()   { /* ... */ }
      void spieler_runter() { /* ... */ }
      void spieler_rechts() { /* ... */ }
      void spieler_links()  { /* ... */ }
    
      key_binding key_bindings_; // Unser "switch"
    };
    


  • finix' Lösung ist an sich eleganter, weil der Aufruf nicht durch eine CASE-Entscheidung gelöst wird. Auf der anderen Seite bedeutet dies, dass eine dynamische Liste durchgearbeitet werden muss..

    Wie dem auch sei, diese Funktoren haben mich gerade auf einen Gedanken zwecks ByteCode-Interpreter gebracht ^^



  • @finix

    Danke für die Erklärung! Habs jetzt glaub ich einigermassen verstanden.
    Werds jetzt mal versuchen umzusetzen!


Anmelden zum Antworten