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 ^^
-
Danke für die Erklärung! Habs jetzt glaub ich einigermassen verstanden.
Werds jetzt mal versuchen umzusetzen!