Rubrik: Verschiedenes / Sonstiges | VB-Versionen: VB4, VB5, VB6 | 14.03.05 |
Steuern mit dem Joystick (2 Achsen, 2 Tasten) Abfragen des Joystick Zustandes (X-Achse, Y-Achse, Tasten) | ||
Autor: Radlwimmer Manfred | Bewertung: | Views: 16.999 |
ohne Homepage | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Für manche Anwendungen (z.B. Spiele oder computergesteuerten Geräte) wäre es schön, die Steuerung über einen angeschlossenen Joystick vorzunehmen.
Wie funktioniert das?
- Man kauft sich für ca. 30 Euro ein fertiges Steuerelement, das man nicht verändern, erweitern oder ausbessern kann oder...
- Man liest sich nachfolgenden Tipp durch und lernt vielleicht noch daraus
Prinzipiell kann man alle Ports eines Computers (LPT, USB, ...) mit der inpout32.dll setzen und abfragen. Beim Gameport(Joystickanschluss!) ist das System aber nicht einfach nach "Eingang offen", "Eingang zu" geregelt, sondern etwas durchdachter aufgebaut.
Ein Kondensator wird über den Widerstand im Joystick (Potentiometer an X- und Y-Achsen) geladen, was zu unterschiedlichen Ladezeiten führt. Langer Rede kurzer Sinn: man durchläuft eine Schleife, und zähl mit, wie lange es dauert bis der Eingang auf 1 ist.
Option Explicit ' Zunächst die benötigten Deklarationen Private Declare Function Inp Lib "inpout32.dll" _ Alias "Inp32" ( _ ByVal PortAddress As Integer) As Integer Private Declare Sub Out Lib "inpout32.dll" _ Alias "Out32" ( _ ByVal PortAddress As Integer, _ ByVal Value As Integer) ' Der Gameport Private Const InpJoy As Integer = &H201
Da die oben erwähnten Abfragen in Millisekunden erfolgen, werden die Werte meist ungenau. Ab 50 - 100 Messungen, erhält man aber ziemlich genaue Durchschnittswerte.
Public Function JoyX() As Integer Dim maxmess As Integer Dim i(100) As Long Dim z As Integer Dim a As Long ' Die Schleife wird öfters durchlaufen ' um ein besseres Ergebnis zu erzielen For z = 0 To 100 ' Der Eingang am Gameport (&H201) ' wird auf 0 zurückgesetzt Out InpJoy, 0 i(z) = 0 Do ' Je länger es dauert, desto größer ist der ' Widerstand, und somit die Neigung des Joysticks i(z) = i(z) + 1 ' Wenn kein Gerät angeschlossen ist, würde ' man hier in eine Endlosschleife geraten. Desshalb ' wird nach 255 Versuchen abgebrochen Loop Until (Inp(InpJoy) And 1) = 0 Or i(z) > 255 ' Von den 100 Messwerten wird der Durchschnitt genommen a = a + i(z) Next z JoyX = Int(a / 100) End Function
Das gleiche natürlich auch für die Y-Achse:
Public Function JoyY() As Integer Dim i(100) As Long Dim z As Integer Dim a As Long For z = 0 To 100 Out InpJoy, 0 i(z) = 0 Do i(z) = i(z) + 1 Loop Until (Inp(InpJoy) And 2) = 0 Or i(z) = 255 a = a + i(z) Next z JoyY = Int(a / 100) End Function
Den Status der Tasten zu ermitteln ist hingen viel einfacher, da diese jeweils einen fixen Pin belegen.
Um an den Zustand herranzukommen, zerlegt man den Eingangswert erst einmal in 2er-Potenzen (Binär).
Public Function TasteGedrueckt(TastNr As Integer) As Boolean Dim Value As Integer Dim i As Integer Value = Inp(InpJoy) ' Das Eingangsignal des Gameports wird ' hier in seine einzelnen Pins zerlegt For i = 7 To 4 Step -1 If Value >= 2 ^ i Then Value = Value - 2 ^ i If TastNr = i - 3 Then TasteGedrueckt = False End If Else If TastNr = i - 3 Then TasteGedrueckt = True End If End If Next i End Function
Das Ganze könnte in einer Anwendung dann ungefähr so aussehen:
Private Sub Timer1_Timer() Label1.Caption = "X: " & JoyX & " Y: " & JoyY Label2.Caption = "Taste1 gedrückt: " & TasteGedrueckt(1) Label3.Caption = "Taste2 gedrückt: " & TasteGedrueckt(2) Shape1.Left = JoyX * 10 Shape1.Top = JoyY * 10 End Sub