Zum tausendsten mal: Tastatur-Input (windows.h)



  • Guten Tag alle zusammen.

    Also ich versuche mich gerade mal an einem Konsolen-Tetris-Klon.
    Bisher habe ich - wenn vermutlich schrecklich modularisiert -
    den meisten Code für die wesentlichen Spielfunktionen.

    Ich bin nicht wirklich erfahrener Programmierer (mache es erst seit c.a. nem Jahr hin und wieder mal) und obwohl ich mit den Basics von C++ einigermaßen vertraut bin, hab ich schon gemerkt dass so ein Spiel erstmal nicht trivial ist.

    Mein Problem ist, ich habe keine Ahnung wie ich abfragen soll ob der Spieler meinetwegen W,A,S,D oder oder drückt. Ich habe schon einige Codebeispiele aus
    der Windows.h gesehen, die dann so Befehle wie GetAsynchKeyState benutzt, aber
    so richtig schlau werde ich nicht. Meistens werden diese Abfragen in Schleifen gehandhabt wie es scheint. Aber wenn dann da sowas spielt wie while(1){ //Code }, frag ich mich: Wie komm ich denn da wieder aus?

    Mir sind da auch die Konzepte hinter - vermutlich - nicht bekannt.

    Mein Programm speziell sollte eig. eine Schleife haben, in der quasi ein mal pro Umdrehung der Input abgefragt wird, dann werden Spieldaten verarbeitet und am Ende wird alles in die Konsole grafisch (also in ASCII Zeichen 😃 ) ausgegeben.

    Ich bin mir mittlerweile nicht mehr so sicher ob der Ansatz es auch bringt.
    Kann mir jemand nen Roten Faden geben? Falls jemand ein Beispielspiel kennt mit Source Code wäre ich auch dankbar. Ich würde neben den Befehlen die es braucht vor allem gerne wissen, wie die Inputverarbeitung ins große ganze passt.

    Mit freundlichen Grüßen,

    Thez



  • while (1)
    {
       // Input verarbeiten
       wenn ("a" gedrückt?)
           SchiebeLinksRechts(-1);
       wenn ("d" gedrückt?)
           SchiebeLinksRechts(1);
       wenn ("s" gedrückt?)
           Runter();
       wenn (Escape gedrückt?)
           break; // <---- Schleife verlassen
    
       // Block fallen lassen
       wenn (Zeit für automatisch Fallen verstrichen?)
           Runter();
    
       // Ganze Zeilen entfernen und Game-Over Handling
       EntferneGanzeLinien();
       wenn (stehn wir oben an?)
           break; // <---- Schleife verlassen
    
       // Timing
       Sleep(mal kurz eben);
    }
    

    ?

    Grundsätzlich: aus einer while (1) kommst du mit zumindest folgenden Konstrukten wieder raus:

    • break
    • return
    • throw
    • goto
    • longjmp

    Wobei die letzten beiden in einem C++ Programm mMn. nix verloren haben, und throw auch nur verwendet werden sollte um halt wirklich Fehler zu behandeln (was auch immer man jetzt unter Fehler versteht, aber "User hat Escape gedrückt" oder "Game-Over" sind wohl eher keine Fehler => throw nicht dafür verwenden).



  • Hab's jetzt tatsächlich doch noch selbst hinbekommen und das ganze wirkt doch ganz Stabil. Auch eine neue Renderfunktion gebastelt damit das ganz nicht mehr flimmert.

    Habe die Tastaturabfrage nun mit getch() und kbhit() gemacht. Dein Beispiel bestätigt aber das, was ich nun probiert habe. Ich glaube, jetzt hat es auch erstmal geklickt.

    Ich fürchte aber, getch() und kbhit() reichen nur für so simple Eingabefunktionen wie bei Tetris. 😕 Und die windows.h Funktionen sind mir erstmal noch zu kryptisch.

    Danke für die Hilfe, dennoch 😃



  • An GetAsyncKeyState ist eigentlich nix kryptisch.

    bool istShiftGedrückt = (GetAsyncKeyState(VK_SHIFT) & (1 << 15)) != 0;
    bool istAGedrückt = (GetAsyncKeyState('A') & (1 << 15)) != 0;

    OK, was u.U. nicht so einfach zu finden ist, ist dass die virtual key codes für A...Z den ASCII Codes der Grossbuchstaben entsprechen. Und es deswegen fieserweise keine VK_A, VK_B ... VK_Z Konstanten gibt.
    Das selbe nochmal mit 0...9.



  • hustbaer schrieb:

    An GetAsyncKeyState ist eigentlich nix kryptisch.

    Klar. Der Ausdruck " & (1 << 15) " ist ja auch voll intuitiv und absolut logisch und nachvollziehbar.



  • Steht alles in der Doku (MSDN).
    Es ging ja nicht darum die Zeile (ohne Doku) lesen zu können, sondern darum anhand der Doku rauszubekommen wie man GetAsyncKeyState verwendet.

    Davon abgesehen: ja, wenn man C++ kann und weiss wie das Binärsystem funktioniert, dann ist der Ausdruck logisch und ganz einfach nachvollziehbar.



  • Ich weiß, wie das Binärsystem funktioniert. & ist der bitweise AND-Operator und << ist das Bit-Shiften.
    Ich meinte nur: Es ist nicht gerade intuitiv, wenn man bei einer vorgefertigten WinAPI-Funktion noch mit irgendwelchen festen Nummern (1, 15) binär rumfriemeln muss.
    Ich hätte erwartet, dass man bei einer Funktion GetAsyncKeyState einfach 0 oder 1 zurück bekommt und das war's.
    Wenn man bei einer einer Bibliotheksfunktion den Rückgabewert noch shiften und AND-verknüpfen muss, obwohl der Status rein intuitiv eigentlich ein boolescher Wert sein sollte (gedrückt oder nicht gedrückt), dann ist das kryptisch.



  • Dann haben wir offenbar unterschiedliche Vorstellungen davon was kryptisch ist.
    Aber nochmal: es ging um die Doku. Und da ist das Verhalten ganz klar beschrieben. Das kryptisch zu nennen finde ich reichlich seltsam.


  • Mod

    BillyD schrieb:

    Ich hätte erwartet, dass man bei einer Funktion GetAsyncKeyState einfach 0 oder 1 zurück bekommt und das war's.

    Gibt's denn als State einer Taste nur zwei Möglichkeiten? Eben nicht, daher ist das auch so wie es ist. Wenn man nahe an der Hardware programmiert, bekommt man eben die volle Information, meistens auch noch ungefiltert oder nahezu ungefiltert. Wenn das eine high-level Funktion in einem Framework, a la IsKeyPressedRightNow, wäre, dann wäre etwas anderes als ein bool verwunderlich.


Anmelden zum Antworten