Abfrage eines Zeichens aus dem Konsoleninput ohne kurze Pause nach ersten Zeichen
-
Grüße
.
Ich konnte folgendes Problem mit Hilfe des mir zur Verfügung stehenden World Wide Web nicht lösen. Es liegt warhrscheinlich erst einmal daran, dass ich dem Namen dieses [ES] nicht kenne:
Nehmen wir an, ich drücke die Taste 'x'. Gaaanz lange und fest. Es erscheint das erste 'x' im Input-Buffer (oder auch auf dem Screen). Danach (ich drücke die Taste 'x' immer noch gaaaanz doll) MUSS ich eine kleine Weile warten. Und erst nach dieser Pause (in der ich die Taste 'x' gaaanz doll festdrücke) erscheinen die nächsten 'x'e ohne zeitliche Unterbrechung im Input-Buffer.
Also 2 Fragen:
1. Wie heißt diese unsägliche Pause oder diese ganze Konstrukt, dass ja nur bei Texteingabe sinnnvoll ist, damit ich nur ein 'x' und nicht 4 bis 8 'x'e pro Tastenschlag im Programm auftauchen.
2. Was muss ich tun, damit ich [ES] einsetzen kann, wann ich es will und nicht immer.Ich denke, dass man das über irgendeinen Modus der Konsole einstellen kann. Aber ich such schon seit einigen Stunden und langsam bekomm ich die Krise
Ich dachte, als ich im iNet geforscht hab, dass dieses Problem häufig anzutreffen ist, aber nix da. Nix, gar nix
. Also entweder die Lösung ist so trivial, dass ich nicht daraufkomme oder es wird Zeit für mich mal die Füße hochzulegen und bisschen zu chillen.
Danke jetzt schon Mal für produktive Beiträge
.
-
Wie heißt diese unsägliche Pause oder diese ganze Konstrukt, dass ja nur bei Texteingabe sinnnvoll ist, damit ich nur ein 'x' und nicht 4 bis 8 'x'e pro Tastenschlag im Programm auftauchen.
Nennt sich Zeichenwiederholungsverzögerung. Zumindest steht das in der Systemsteuerung.
Zur zweiten Frage:
Die Wiederholungsverzögerung kannst Du mit der API Funktion 'SystemParametersInfo' setzen. Als Parameter musst Du der Funktion dabei die Konstante SPI_SETKEYBOARDDELAY übergeben. Den Rest erklärt Dir die MSDN.
-
kannst dir auch einen eigene funktion bauen wenn du es kompatiebel haben möchtest
kann ja sein das du dieses programm nicht nur unter windows benutzen willst sondern auch unter linux
-
Danke, dass ist ja schon mal ein Schritt.
Ich persönlich finde es aber hässlich im System rumzupfuschen, nur damit ich ne wiederholte Tastenabfrage realisieren kann.
Gibt es da nicht noch eine andere Möglichkeit, den Tasteninput des Users in der Konsole abzufragen, ohne dass ich erst die Zeichenwiederholungsverzögerung auf 0 setze?
@GAMES:
Wenn du mir sagst wie eine solche Funktion auszusehen hat.PS: Primär für Windows bzw. würde das schon reichen.
Und noch ein PS: Wenn ich Zeichenwiederholungsverzögerung heißen würde, würde ich mich umbringen, der Name gehört verboten.
Das sind ja genau so viele Silben wie BAföG ausgesprochen hat.
-
The Key schrieb:
Gibt es da nicht noch eine andere Möglichkeit, den Tasteninput des Users in der Konsole abzufragen, ohne dass ich erst die Zeichenwiederholungsverzögerung auf 0 setze?
Jetzt geht's Dir aber plötzlich um ganz was anderes, vorher war nur von der Verzögerung die Rede! Ich verstehe Dein Anliegen trotzdem noch nicht richtig. Zeichen kannst Du mit std::cin, oder ohne Echo, und Zeichenweise mit getch() ausgeben. Aber wo genau liegt das Problem? Kannst Du Dich etwas genauer ausdrücken?
-
Kannst du Dir da nicht vorstellen, welche Art von Funktionalität ich implementieren möchte?
Ich erkläre es mal an einem kleinem Beispiel:
Ein Quasi-Jump'n'Run:
Ein Männchen auf einer Linie.
Wenn der User zum Beispiel die Pfeiltaste rechts drückt, dann soll das Männchen sich natürlich ohne diese verzögerung nach rechts bewegen.Das ist die ganze Geschichte.
Das da natürlich noch mehr Probleme, wie gleizeitiges Drücken zweier Tasten auftritt, wenn ich _getch() verwende, ist klar.
Aber ich habe mein Augenmerk erst einmal auf diese Verzögerung gelegt.
-
du brauchst bei einen jamp ´n´run mit gegner und auch ohne eine verzögerung!!!
sonst ist dein mänchen in einem bruchteil von einer sekunde degen was gerand ohne das du drüber springen kann dafür eigenet sich unter windows Sleep() aus der windows.h oder du kannst dir auch eine eigene funktion bauenvoid mywait (int); void mywait(int d) { struct time t, tneu; int loop; for (loop=0; loop<d; loop++) { gettime(&t); gettime(&tneu); while (t.ti_hund == tneu.ti_hund) gettime(&tneu); } }
die funktion stammt nicht von mir hat jemand anderst geschrieben
für die eingabe ist getch() geeigned sowie vll kbhit()
mit diesem wissen müstest du die funktion schon hinbekommen
-
The Key schrieb:
Wenn der User zum Beispiel die Pfeiltaste rechts drückt, dann soll das Männchen sich natürlich ohne diese verzögerung nach rechts bewegen.
Da bleibt Dir aber leider nichts anderes übrig, als tatsächlich die systemweite Variable für die Tastenverzögerung umzustellen. Das muss dann aber nicht zwangsläufig bedeuten, dass es sich auf das gesamte System ausweitet. Mit einer einfachen Abfrage, ob das Konsolenfenster gerade aktiv ist, kannst Du verhindern, dass die Tastenverzögerung auch ausserhalb Deines Programmes greift. Sobald also das Fenster in den Hintergrund gerät, einfach wieder auf Default-Verzögerung umstellen.
Kurzes Beispiel:
if(::GetActiveWindow() == ::FindWindow(NULL, "ConsoleWindowClass")) { // Konsolenfenster im Vordergrund, also aktiviert, systemweite Tastenverzögerung // kann herab gesetzt werden. }
Ich hoffe, das hilft Dir weiter.
-
ich würde eh für den anfang von den pfeiltasten abraten eher "awsd" da die pfeiltasten kein ASCII/ANSI-Code zugewiesen ist
und ich selbst hab keie richtige oder sichtbare verzögerung in einem von mir selbstgeschriebenen snake die schlange bewegt sich nach rechts wenn ich d drück und das in meinen augen sofort und nicht entscheidend ok ich überprüf nicht immer ob die taste gedrückt ist ich überprüf ob einen andere gedrückt wurde aber in deinem fall kannst du prüfen ob die taste noch gedrückt ist
kann auch sein das ich dein problem nicht richtig versteh
-
okay. Das ist verstanden.
Und hast du auch eine Lösung für mein zweites Problem? Zwei oder mehrere Tasten gleichzeitig zu überprüfen auf 'Gedrückt' oder 'Nicht Gedrückt' oder ist das bei Konsolenanwendungen nicht möglich?
-
GAMES schrieb:
ich würde eh für den anfang von den pfeiltasten abraten eher "awsd" da die pfeiltasten kein ASCII/ANSI-Code zugewiesen ist
Aber das ist doch kein Grund, gleich von den Pfeiltasten abzuraten. Beim Drücken der Pfeiltasten (u.A.) wird ein entsprechender, standarisierter Sondercode zurück gegeben, auf den man dann entsprechend reagieren kann. Wo liegt dann also das Problem?
-
@GAMES:
Ja, stimmt schon.
Aber bei meinen SNAKE gings auch mit Pfeiltasten und auch wie du sagtest reagiert die Schlange sofort.
Das ist aber nicht das Problem. Mein Problem ist, dass nach dem Gedrückthalten einer Taste 'x' eine Pause nach der Ausgabe des ersten Zeichens 'x' passiert. Und erst nach dieser Pause kommen die Zeichen 'x' ohne Unterbrechung, und ich weiß, dass der User diese taste ununterbrochen drückt.
mikey nannte es Zeichenwiederholungsverzögerung.Aber danke für die Anmerkung
-
The Key schrieb:
Und hast du auch eine Lösung für mein zweites Problem? Zwei oder mehrere Tasten gleichzeitig zu überprüfen auf 'Gedrückt' oder 'Nicht Gedrückt'
Da fällt mir grad' spontan nur GetAsyncKeyState() aus der Win API ein... sonst fällt mir auch keine bessere Lösung ein. Einfach mal auf der MSDN gucken. Diese Referenz kann dir manchmal auch ganz gut weiter helfen:
http://msdn2.microsoft.com/en-us/library/ms682073(VS.85).aspxSoviel kann ich aber schonmal sagen, dass es keine Standard C++ Lösung dafür gibt... Entweder, du bastelst dir etwas mit _getch und _kbhit zusammen (denke ich, klappt so nicht), oder du weichst auf die wesentlich unsaubere Methode mit der API aus. Oder du schreibst dir gleich einen eigenen Keyboard-Hook.
-
mikey du kannst mir warscheinlich auch sagen wie ich peiltasten ohne pfusch richtig auslesse vll sogar mit kleinem bsp cod
-
Danke. Das hat mir schon sehr geholfen. Ist zwar noch nicht ganz perfekt, aber nah dran.
@GAMES:
intkey = 0; do { if(_kbhit()) { key = _getch(); if(key == 'A') { // shift + 'A' is pressed } else if(key == 'a') { // 'A' is pressed } else if(key == 224) { key == _getch(); if(key == 75) { // key left is pressed down } else if(key == 77) { // key right is pressed down } } } } while(key != 13);
So sieht das bei mir immer aus.
-
hab ne gepfuschte version die wird jetzt überarbeidet ich frag mich wie die eig laufen kann fraglich aber jetzt wirds verbessert
zu deinem problem mit dem gleichzeitig glaub wenn du 2 tasten drückst werden die nacheinander eingegeben vll kannst ja deine eingaben in einem array speichern und die dann auswerten auf diese weiße würd ich versuchen das problem zu lösen
ein array der genau oder max 2 eingaben speichert und diese nach der auswertung\weiterverarbeitung löscht
ich denk mal dein mänchen soll nur vor zurück springen und vll sich ducken können
-
Ich kann das Problem von The Key problemlos nachvllziehen. Habe aus dem gleichen Grund "nur" ein Snake programmiert da man da ja nicht die taste gedrückt halten muss.anscheinend liegts an kbhit(); das funktuniert nicht so wies sollte^^
-
GAMES schrieb:
mikey du kannst mir warscheinlich auch sagen wie ich peiltasten ohne pfusch richtig auslesse vll sogar mit kleinem bsp cod
Aber immer gerne doch:
eing = getch (); switch(eing) { case 72: /* Nach oben-Taste */ break; case 80: /* Nach unten Taste */ break; case 75: /* Nach links-Taste */ break; case 77: /* Nach rechts-Taste */ break; default:break; }
Dede1989 schrieb:
anscheinend liegts an kbhit(); das funktuniert nicht so wies sollte
Nene, das funktioniert schon so, wie es funktionieren soll. Es liegt nur am Anwender
-
Gut ich habe diese WinAPI-Funktionen getestet. Sie machen fast alle was sie sollen.
Was ich jetzt doch noch wissen will:
1. Was wäre denn an Standard besser, weil du etwas von 'unsauber' sagtest.
2. GetKeyboardState liefert nicht keine vernünftigen Werte. GetAsyncKeyState tut zwar auch seine Schuldigkeit, aber mir würde es doch gefallen, alle Werte auf einmal zu erhalten.
-
The Key schrieb:
1. Was wäre denn an Standard besser, weil du etwas von 'unsauber' sagtest.
Eine Standard C++ Lösung ist deshalb immer besser, weil der daraus resultierende Code portabel ist, also auf allen Platformen läuft. Lösungen, die z.B. mit getch() und anderen Funktionen aus diversen non-Standard Headern arbeiten, müssen sich nicht zwangsläufig unter jedem Compiler kompilieren lassen, da es nicht vorgeschrieben wird, ob diese mitgeliefert werden müssen, oder nicht.
The Key schrieb:
2. GetKeyboardState liefert nicht keine vernünftigen Werte. GetAsyncKeyState tut zwar auch seine Schuldigkeit, aber mir würde es doch gefallen, alle Werte auf einmal zu erhalten.
Da gibt es afaik keine fertige Lösung, die wirst du dir selbst in eine Funktion packen müssen.