Mehrere Tastendrücke abfangen

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Kangaroo.

    Mehrere Tastendrücke abfangen

    Hey, liebes VB-Paradise-Forum (:

    Ich habe ein Problem bei einem einfachen Pong-Spiel, das ich programmiere.
    Ein ähnliches Spiel habe ich bereits einmal mit Java programmiert, mit einem ähnlichen Problem, das auch mein Informatiklehrer mir nicht lösen konnte (war einfach so eine kleine Sache, die ich außerschulisch mal programmiert hatte).
    Es geht darum, dass wenn einer der beiden Spieler seinen Pong bewegt, der andere seinen nicht mehr bewegen kann - das Programm liest immer nur einen der beiden Tastenanschlägen aus.
    Das ganze habe ich dann mit folgendem Code versucht zu lösen:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub StartButton_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles StartButton.KeyDown
    2. 'KeyDown = 40
    3. 'KeyUp = 38
    4. 'S = 83
    5. 'W = 87
    6. If CompKey(40) And CompKey(83) Then
    7. rightDown()
    8. leftDown()
    9. Else
    10. If CompKey(40) And CompKey(87) Then
    11. rightDown()
    12. leftUp()
    13. Else
    14. If CompKey(38) And CompKey(83) Then
    15. rightUp()
    16. leftDown()
    17. Else
    18. If CompKey(38) And CompKey(87) Then
    19. rightUp()
    20. leftUp()
    21. Else
    22. If CompKey(40) Then
    23. rightDown()
    24. End If
    25. If CompKey(38) Then
    26. rightUp()
    27. End If
    28. If CompKey(83) Then
    29. leftDown()
    30. End If
    31. If CompKey(87) Then
    32. leftUp()
    33. End If
    34. End If
    35. End If
    36. End If
    37. End If
    38. End Sub

    Das ganze macht also nichts anderes als:
    Pfeilhoch = rechter Pong hoch
    Pfeilrunter = rechter Pong runter
    W = linker Pong hoch
    S = linker Pong runter

    Der Code funktioniert jedoch nicht ganz... naja - okay, er funktioniert überhaupt nicht ^^

    Funktion CompKey ist hier:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function CompKey(ByVal KCode As Long) As Boolean
    2. Dim Result As Integer
    3. Result = GetAsyncKeyState(KCode)
    4. CompKey = (Result = -32767)
    5. End Function


    Die CompKey-Abfrage scheint ganz gut zu funktionieren, da es bei einem einzelnen Befehl, wie zB

    VB.NET-Quellcode

    1. If CompKey(40) Then
    2. rightDown()
    3. End If

    alles richtig läuft.
    Kombiniert man jedoch die Abfragen, dann funktionert nichts - ich hoffe das liegt nicht daran, dass ich die kopierte Methode CompKey, einfach ganz dreist kopiert und hingenommen habe ^^

    Was ich einfach will, ist, dass das Programm erkennt, wenn man zwei Tasten gleichzeitig herunterdrückt, und zwar auch, welche das sind ^^
    Kann mir jemand einen Tipp geben? ^^ Mein Lehrer meinte damals, das läge am Tastaturpuffer...

    MfG
    LevelXProject

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „LevelXProject“ ()

    Du musst nur für jede zu überwachende Taste eine Globale Variable erstellen vom Typ bool erstellen, in der du speicherst, ob die Taste gedrückt ist, oder nicht. Den Wert dieser Variablen kannst du im KeyDown/Up-Event setzen, um die Werte zu updaten.

    Du verwendest wahrscheinlich einen Timer, um das Bild bzw. die Animation, z. B. 25 mal pro Sekunde zu aktualisieren. Dazu stehen dir dann die Werte der Variablen zur Verfügung, welche Tasten im Moment gedrückt sind.
    in WinForms würde ich die KeyDown/KeyUp - Events behandeln. Ein Key ist gedrückt ab dem Zeitpunkt des KeyDown-Events bis zum Zeitpunkt des KeyUp-Events.
    Das KeyDown/KeyUp - Event beliefert dich in den EventArgs mit Information, um welchen Key es sich handelt - eine CompKey-Funktion ist unnötig.

    (was wissen eigentlich Informatik-Lehrer?)
    nein
    Ist irgendetwas schwer verständlich an
    Ein Key ist gedrückt ab dem Zeitpunkt des KeyDown-Events bis zum Zeitpunkt des KeyUp-Events.
    Das KeyDown/KeyUp - Event beliefert dich in den EventArgs mit Information, um welchen Key es sich handelt
    ?

    Aber ich schmeisse grad mein eigenes Konzept übern Haufen:

    So Pong-mäßig müssteste doch einen Timer verwenden, der im TimerTick mw mitte CompKey-Funktion checkt, welche der 4 Tasten gedrückt sind. So kann man mw. alle 200ms die Positionen der Schläger und des Balles verändern.
    Das wäre jetzt ein Modell ganz ohne KeyDown/Up/Press, sondern nur mit einem Timer und CompKey

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Mh - eine simple, aber doch ernüchternde Antwort ^^

    Leider weiß ich nicht genau, worauf du hinausmöchtest.
    Den wert frage ich ja bereits aus eventArgs ab, als variable e
    wie kann ich nun das Problem lösen, dass er immer nur einen einzigen Tastendruck erkennt, wenn man zwei tasten gleichzeitig drückt - nämlich die taste, die man als letztes gedrückt hat?

    Okay - ich versuch's mal ^^

    Okay - hier, so müsste es doch sein, oder?

    VB.NET-Quellcode

    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2. If CompKey(40) Then
    3. rightDown()
    4. End If
    5. If CompKey(38) Then
    6. rightUp()
    7. End If
    8. If CompKey(83) Then
    9. leftDown()
    10. End If
    11. If CompKey(87) Then
    12. leftUp()
    13. End If
    14. End Sub


    Es funktioniert allerdings wieder nur eine einzige taste, und nicht zwei oder mehr gleichzeitig.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „LevelXProject“ ()

    Hmm... hab ich denn irgendetwas nicht beachtet oder falsch geschrieben in dem Code?

    VB.NET-Quellcode

    1. Private Function CompKey(ByVal KCode As Long) As Boolean
    2. Dim Result As Integer = GetAsyncKeyState(KCode)
    3. CompKey = (Result = -32767)
    4. End Function
    5. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    6. If CompKey(40) Then
    7. rightDown()
    8. End If
    9. If CompKey(38) Then
    10. rightUp()
    11. End If
    12. If CompKey(83) Then
    13. leftDown()
    14. End If
    15. If CompKey(87) Then
    16. leftUp()
    17. End If
    18. End Sub
    Schau dir doch mal deine CompKey-Funktion genau an. Die wird wahrscheinlich niemals, auch wenn nur eine Taste gedrückt ist true zurückgeben. Verwende die WinAPI-Funktion so, wie in dem Thread den ErfinderDesRades schon verlinkt hat (oder am besten mit der Dll-Import-Schreibweise).

    Alternativ, mach es doch einfach so wie ich in der 1. Antwort geschrieben habe. Das funktioniert normalerweise schon mit mehreren Tasten und es wird kein WinAPI-Aufruf benötigt, somit wäre dein Programm noch halbwegs unabhängig von der Plattform.
    @TE, EDR: Ihr beide habt Euch schon einmal die Dokumentation von GetAsyncKeyState durchgelesen , oder ?

    If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.

    Also solltet Ihr den Return Code mit &H8000 maskieren um festzustellen ob die Taste gedrückt ist, das Low Order Byte signalisiert was anderes.
    z.B: dim pressed as boolean= ((GetAsyncKeyState(Keys.A) And &H8000) = &H8000))

    Nachtrag: aus dem Profil von LevelXProject Glücklicher Veggie und Furry : die (bedauernswerten) Veggies kenne ich ja gerade , aber was zum Teufel ist ein Furry (Jürgen Klopp vor dem Friseur ?) ...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Kangaroo“ ()