Mehrere Gamepad Buttons gleichzeitig abfragen

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Mangafreak1995.

    Mehrere Gamepad Buttons gleichzeitig abfragen

    Hallo zusammen,
    ich habe ein riesen Problem was mich schon seit Monaten beschäftigt, doch ich nicht mehr weiter weis.
    Ich möchte folgendes Programmieren: Ein Joystick soll abgefragt werden. Es sollen alle verfügbaren Buttons aufgelistet werden. Es soll jeder Button abgefragt werden ob er gedrückt ist oder nicht. Schon bei den auflisten der Buttons komme ich nicht weiter. Ich habe bis jetzt nur die Abfrage der Buttons wobei ich immer nur einen Wert bekomme. Entweder Button 4 oder kein Button ist gedrückt. Gleichzeitiges abfragen aller Buttons bekomm ich einfach nicht hin.

    Hat jemand eine Lösung?

    Mein bisheriger Code:

    VB.NET-Quellcode

    1. Dim JInfo As JOYINFO
    2. Private Declare Function joyGetPos Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef pji As JOYINFO) As Integer
    3. joyGetPos(0, JInfo)
    4. msgbox("Button " & Str$(JInfo.Buttons) & " ist gedrückt.")
    also ich würde es mit DirectInput lösen, da hast du ne Enum, mit welcher du überprüfen kannst, ob genau dieser Button gedrückt worden ist(und durch durchlaufen der Enum bei jedem Button) hundertprozent gleichzeitig ist nicht möglich, aber die Variable ändert sich in dieser Zeit auch nicht...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    idi.ntnu.no/~fredrior/files/Joystick.NET/Joystick.cs

    ein bisschen Googlen(ich habe länger gebraucht um diesen Tab wieder zu finden, als diesen Source...xD)...und das ist leicht zu portieren...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Hallo zusammen,
    leider liegt dieses Thema schon länger zurück, aber damit jeder den Zusammenhang versteht möchte ich kein neues Thema eröffnen.

    Es hatte sich eigentlich alles geklärt da ich das Gamepad nicht mehr benötigt habe. Doch nun hab ich es wieder aufgegriffen.
    Ich habe es soweit programmiert das in einem String der aktuell gedrückte Button geschrieben wird (siehe oben). Mit einem bisschen veränderten Code werden nun alle Buttonwerte zusammenaddiert.

    Beispiel: Button 1 hat den Wert 2
    Button 2 hat den Wert 5

    werden nun Button1 und 2 zusammen gedrückt erscheint der Wert 7.

    Bei 2 Button kann man den Wert mit einer For Schleife noch leicht trennen um die einzelnen Werte herauszufinden. Doch wenn das Gamepad 15 Knöpfe hat und der Benutzer mal 1 mal 2 , 3 oder 5 verschiedene Buttons zusammen drückt, kann ich es nicht mehr trennen.

    Hat jemand eine Idee wie man das am besten Ressourcen schonend programmieren kann?

    PS: Einzelwerte sind jeweils bekannt.
    Die Werte sind glaub ich von Gamepad zu Gamepad unterschiedlich. Die 5 war ja nur ein Beispiel. Hier die Liste meines:

    Button Wert
    1 1
    2 2
    3 4
    4 8
    5 16
    6 32
    7 64
    8 128
    9 256
    10 512

    Der Zusammenhang ist ja das jede nächste Zahl die vorherige Zahl * 2 ist.

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

    Doche, es gibt einen Zusammenhang. Wie FAtheone schon geschrieben hat, ist jedem Button ein Bit zugeordnet. Jedes Bit hat einen Wert von 2^n (Du mußt dann nur die Buttons 0-basiert sehen also Button 1 = 2^0 = 1)
    Damit kannst du den zurückgegebenen Wert wieder bitweise auslesen.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Danke dir!

    Nun kenne ich ja den Zusammenhang doch wenn der Benutzer x Button zusammendrückt bekomme ich ja einen addierten Wert. Ich weiß aber nicht wieviel er zusammendrückt, aber ich muss die einzelnen Werte irgendwie bekommen.

    Es geht darum: Der Benutzer steckt ein beliebiges Gamepad an. Im Beispiel hat es 4 Buttons (Werte wie oben). Dieses schließt er an ein Mischpult an (Gamepad wurde umgelötet zum Faderstart). Er schiebt nun Fader 1 hoch, button1 ist damit dauerhaft gedrückt das Programm bekommt den Wert 1. Nun lässt der Benutzer den Fader noch oben schiebt aber Fader 2 und 3 auch noch nach oben sind sozusagen 3 Buttons gedrückt. Der Wert 7 wird ausgegeben (1 + 2 + 4). Wie kann mein Programm nun wissen was alles hochgezogen ist? Eine Trennung mit 2 Werten bekomme ich hin. In der Listbox sind alle Einzelwerte aufgelistet.

    VB.NET-Quellcode

    1. For i As Integer = 0 To ListBox1.Items.Count - 1
    2. For b As Integer = 0 To ListBox1.Items.Count - 1
    3. If ListBox1.Items(i) + +ListBox1.Items(b) = gedrückt Then
    4. Label2.Text = "Button1 = " & ListBox1.Items(i) & vbCrLf & "Button2 = " & ListBox1.Items(b)
    5. Exit For
    6. End If
    7. next
    8. next

    Ich möchte es aber so dynamisch wie möglich haben, da der Benutzer ja beliebig viele Buttons zusammendrücken kann.
    Also mit diesem C&P solltest du das gebacken bekommen:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim Bits(7) As Boolean
    3. Dim Eingabe As Byte
    4. If Byte.TryParse(TextBox1.Text, Eingabe) Then
    5. Bits = BitConv(Eingabe, 8)
    6. Ausgabe(Bits)
    7. Else
    8. TextBox1.Text = "ungültige Eingabe"
    9. End If
    10. End Sub
    11. Function BitConv(ByVal Eingabe As Byte, ByVal BitAnzahl As Integer) As Boolean()
    12. Dim Exp As Integer = BitAnzahl - 1
    13. Dim Bits(7) As Boolean
    14. For e = Exp To 0 Step -1
    15. If Eingabe >= 2 ^ e Then
    16. Bits(e) = True
    17. Eingabe = CByte(Eingabe - 2 ^ e)
    18. End If
    19. Next
    20. Return Bits
    21. End Function
    22. Sub Ausgabe(ByVal Bits() As Boolean)
    23. CheckBox1.Checked = Bits(0)
    24. CheckBox2.Checked = Bits(1)
    25. CheckBox3.Checked = Bits(2)
    26. CheckBox4.Checked = Bits(3)
    27. CheckBox5.Checked = Bits(4)
    28. CheckBox6.Checked = Bits(5)
    29. CheckBox7.Checked = Bits(6)
    30. CheckBox8.Checked = Bits(7)
    31. End Sub

    Du benötigst eine Form mit Textbox, Button und 8 Checkboxen.
    Mit der Übergabe der BitAnzahl an die Sub BitConv kannst du beliebig viele Bits aus einem Integer ableiten.

    Fiel Fergnügen

    Vatter

    Edit du mußt natürlich ggf. das Datenformat der Eingabe von Byte auf Integer ändern.
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Genau das habe ich gesucht. Ich werde nun versuchen den Code nicht nur einfach zu verwenden sondern auch zu verstehen. Da ich mit Bytes nochnicht viel am Hut hatte. Der Code ist nun wirklich dynamisch so wie ich es benötige. Es ist auf jeden Fall auch Ressourcen schonender als ein Fester 100 Meter langer Code der alle Werte wie ein Passwortknacker durchprobiert bis die richtigen einzelwerte gefunden wurden.

    Ich sage herzlichen Dank! Auf sowas wäre ich nie gekommen!!!!
    Bah. Das ist aber unsauber.

    VB.NET-Quellcode

    1. Private Function TasteGedrückt(Taste As Integer, Flag As Integer) As Boolean
    2. Return ((Flag And (1 << Taste)) = (1 << Taste))
    3. End Function


    Einzeiler, der dasselbe macht.

    //EDIT:

    -Rückgabetyp
    -Noch schnellerer Code mit Bitshift

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FAtheone“ () aus folgendem Grund: Codeverbesserung

    ok ... jetzt haben wirs mitm Ihh :D

    ich hab Option Strict On im Standard ;) ... und ohne IDE kannst du keinen vernünftigen Code schreiben ? tztztz *joke*


    BTT
    *rejoke*
    The joke's on you.
    Ich hatte nur die Formel im Kopf, nicht die "Funktion".
    Gewissermaßen behindert ein vor allem das fehlende Syntax-Highlighting, IntelliSense und die Automatische Block-Schließung (Mancherleut vergisst schon End If etc...)

    Da Wichtige ist, dass mein code auf Bitebene und damit quasi direkt mit den Logischen Gates, statt mit den direkt darüber liegenden (Addierern).
    Je direkter, desto schneller ;)

    PS:

    Gibt des in VB eigentlich den LShift und RShift-Operator (wie in C: 1 << 3 = 0001 um 3 Bits nach links versetzt = 1000 (= 8 = 2^3))?

    //EDIT:

    Laut hier schon. Ich probier's mal aus.