Schnellere Tastaturabfrage



  • Hallo alle miteinander,

    in meinem neuen Projekt will ich eine Grafik über die Oberfläche wandern lassen und zwar mit den Pfeiltasten. Blöd ist nur, dass KeyDown sehr lange braucht um wieder aufgerufen zu werden, ich weiß leider nicht wie ich das besser ausdrücken soll.

    Auf jeden Fall möchte ich erreichen, dass sobald eine Taste gedrückt sofort die Aktion ausgeführt wird. Halt so lange wie ich die Taste drücke und nicht wie bei KeyDown, dass die Aktion sofort, dann aber erst nach einer ein sekündigen Pause wieder ausgeführt wird.

    void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
    	if(Key==VK_LEFT&&spieler->Left>0) {
    		spieler->Left=spieler->Left-schrittweite;
    	} else if (Key==VK_RIGHT&&spieler->Left<(Form1->ClientWidth-spieler->Width)) {
    		spieler->Left=spieler->Left+schrittweite;
    	}
    	else if (Key==VK_UP&&spieler->Top>0) {
    		spieler->Top=spieler->Top-schrittweite;
    	}
    	else if (Key==VK_DOWN&&spieler->Top<(Form1->ClientHeight-spieler->Height)) {
    		spieler->Top=spieler->Top+schrittweite;
    	}
    }
    

    Kennt Ihr ein Möglichkeit, wie ich dieses Ziel erreichen könnte?

    Gruß
    Kasimir



  • Hallo,

    du könntest einen Timer verwenden. Diesem im OnKeyDown starten, und im OnKeyUp wieder stoppen. Der Timer führt dann die Aktion aus die zur Zeit im OnKeyDown ausgeführt wird. Anhand des Intervals kannst du die Geschwindigkeit festlegen.

    LG, Micha



  • Mittels KeyDown ist das ja abhängig von deinen System-Tastatureinstellungen (Verzögerung sowie Wiederholrate), aber das hast du ja schon erkannt -)

    Eine Möglichkeit wäre ein Timer in Verbindung mit der WinAPI-Funktion GetAsyncKeyState (gibt genügend Beispiele dazu im Netz oder auch hier im Forum) - die minimale Auslösung des Timerereignisses läge dann bei ca. 14-15 Millisekunden.
    Die andere Möglichkeit wäre ähnlich, jedoch mit anderer Vorgehensweise:
    du registrierst im KeyDown bzw. KeyUp-Ereignis einfach nur den Tastendruck, d.h. merkst dir dafür in einer boolschen Variable den Tastenzustand.
    Und im Timer bewegst du dann dein Objekt, solange die Variable gesetzt ist.

    Für eine exakte /gleichmäßige) Bewegung bräuchtest du aber eine eigene Game-Loop, welche sich mit der Anzahl der Frames synchronisiert (nur so als Hinweis -).

    P.S. "Form1->" ist bei dir überflüssig, da dein Event sich ja innerhalb von Form1 befindet (wenn schon explizit, dann besser "this->" verwenden).



  • das problem was ich vorher hatte, denn RandomAccess85s Versuch hatte ich auch schon porbiert, war, dass der Timer ja kein Key kennt. Allerdings habe ich nun ein WORD juspressk erstellt in das ich beim OnKeyDown die gedrückte Taste lege und sie dann im Timer auswerten kann.
    So gehts momentan recht gut!

    Das mit dem GetAsyncKeyState(); hab ich hier im Forum nur als Empfehlung gelesen und auf Seiten wo das beschrieben steht fand ichs auf den ersten Blick zu kompliziert 😃 Ich werd das auch mal weiter verfolgen.

    Desweitern drängt sich das Problem auf, wie ich das auf die reihe bekomme die Grafik im 45° Winkel bewegen zu lassen, also die Abfrage von Links und Oben z.B. abzufragen, aber ich glaub dazu wär z.B. GetAsycKeyState(); nicht wahr? Wie auch immer, danke für die Hilfe! Ich les mich mal in GetAsyncKeyState(); rein!

    Gruß
    Kasimir

    EDIT: Sorry, GetAsyncKeyState(); ist kein stück kompliziert und ich war nur zu faul zum Lesen. Alle Probleme beseitigt! 😉


Anmelden zum Antworten