您的位置:首页 > 编程语言 > VB

游戏手柄编程DEMO 基于 VB.NET+API 暂无力反馈

2013-03-21 20:25 344 查看
完全是一篇DEMO级别,入门级别的编程文章

参考资料:
http://tieba.baidu.com/p/278512011 http://www.cnblogs.com/kingthy/archive/2009/03/25/1421838.html http://www.cnblogs.com/kingthy/archive/2009/03/28/1424055.html
鉴于以上资料可能会被删除,这里做一些总结:

VB6实现代码:

搜索了以下好像吧内没有人贴关于手柄编程的文章,我贴一个XP+VB6.0+usb手柄测试通过 
========================== 
Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Long, pji As JOYINFOEX) As Long 
Declare Function joyReleaseCapture Lib "winmm.dll" (ByVal id As Long) As Long 
Declare Function joySetCapture Lib "winmm.dll" (ByVal hwnd As Long, ByVal uID As Long, ByVal uPeriod As Long, ByVal bChanged As Long) As Long 
  
  
' think they are all necessary though. 
Public Const JOYSTICKID1 = 0 
Public Const JOYSTICKID2 = 1 
Public Const JOY_POVCENTERED = -1 
Public Const JOY_POVFORWARD = 0 
Public Const JOY_POVRIGHT = 9000 
Public Const JOY_POVLEFT = 27000 
Public Const JOY_RETURNX = &H1& 
Public Const JOY_RETURNY = &H2& 
Public Const JOY_RETURNZ = &H4& 
Public Const JOY_RETURNR = &H8& 
Public Const JOY_RETURNU = &H10 
Public Const JOY_RETURNV = &H20 
Public Const JOY_RETURNPOV = &H40& 
Public Const JOY_RETURNBUTTONS = &H80& 
Public Const JOY_RETURNRAWDATA = &H100& 
Public Const JOY_RETURNPOVCTS = &H200& 
Public Const JOY_RETURNCENTERED = &H400& 
Public Const JOY_USEDEADZONE = &H800& 
Public Const JOY_RETURNALL = (JOY_RETURNX Or JOY_RETURNY Or JOY_RETURNZ Or JOY_RETURNR Or JOY_RETURNU Or JOY_RETURNV Or JOY_RETURNPOV Or JOY_RETURNBUTTONS) 
Public Const JOY_CAL_READALWAYS = &H10000 
Public Const JOY_CAL_READRONLY = &H2000000 
Public Const JOY_CAL_READ3 = &H40000 
Public Const JOY_CAL_READ4 = &H80000 
Public Const JOY_CAL_READXONLY = &H100000 
Public Const JOY_CAL_READYONLY = &H200000 
Public Const JOY_CAL_READ5 = &H400000 
Public Const JOY_CAL_READ6 = &H800000 
Public Const JOY_CAL_READZONLY = &H1000000 
Public Const JOY_CAL_READUONLY = &H4000000 
Public Const JOY_CAL_READVONLY = &H8000000 
  
Type JOYINFOEX 
        dwSize As Long                 '  size of structure 
        dwFlags As Long                 '  flags to indicate what to return 
        dwXpos As Long                '  x position 
        dwYpos As Long                '  y position 
        dwZpos As Long                '  z position 
        dwRpos As Long                 '  rudder/4th axis position 
        dwUpos As Long                 '  5th axis position 
        dwVpos As Long                 '  6th axis position 
        dwButtons As Long             '  button states 
        dwButtonNumber As Long        '  current button number pressed 
        dwPOV As Long                 '  point of view state 
        dwReserved1 As Long                 '  reserved for communication between winmm driver 
        dwReserved2 As Long                 '  reserved for future expansion 
End Type 
=============================================== 
以上是模块 
以下是主程序:其中要放上一个shape控件和一个timer,用手柄控制shape左右移动 

Dim myJoy As JOYINFOEX 

Private Sub Form_Load() 
Dim r& 
Dim hwnd& 
Static TheX As Long 
Static TheY As Long 
' Tell form to receive joystick functions. 
r& = joySetCapture(hwnd, JOYSTICKID1, 1, 0) 
r& = joyReleaseCapture(JOYSTICKID1) 
' Get joystick position coordinates and fill in the TheX and TheY 
' variables. 
r& = joyGetPosEx(JOYSTICKID1, myJoy) 
TheX = myJoy.dwXpos 
TheY = myJoy.dwYpos 
End Sub 

Private Sub Timer1_Timer() 
Dim bc As Integer 
Cls 
bc = 100 
myJoy.dwSize = 64 
myJoy.dwFlags = JOY_RETURNALL 
' Cls 
' Get the joystick coordinates. 
r& = joyGetPosEx(JOYSTICKID1, myJoy) 

If r = 0 Then 
                    xx = myJoy.dwXpos     'As Long                '  x position 
                    yy = myJoy.dwYpos     'As Long                '  y position 
                                 '  6th axis position 
                    bb = myJoy.dwButtons   ' As Long             '  button states 
                    nn = myJoy.dwButtonNumber  ' As Long        '  current button number pressed 
                 If yy = 0 Then 
                  Print "游戏柄1的向上键" 
                 Shape1.Move Shape1.Left, Shape1.Top - bc 
                 ElseIf yy = 65535 Then 
                 Print "游戏柄1的向下键" 
                  Shape1.Move Shape1.Left, Shape1.Top + bc 
                 End If 
                 If xx = 0 Then 
                  Print "游戏柄1的向左键" 
                  Shape1.Move Shape1.Left - bc, Shape1.Top 
                 ElseIf xx = 65535 Then 
                  Print "游戏柄1的向右键" 
                  Shape1.Move Shape1.Left + bc, Shape1.Top 
                 End If 
                For i = 0 To 9 
                 temp = (bb And 2 ^ i) / (2 ^ i) 
                 If temp = 1 Then 
  
                  Print "游戏柄1的" & i + 1 & "号键" 
                 End If 
                 temp = 0 
                 Next i 
                 temp = 0 
                  If nn > 0 Then 
                Print "一共按下了" & nn & "个键" 
                 End If 
End If 
End Sub


代码简洁通俗易懂,相信学过VB的人都能看得懂

本文结合后两篇文章做了VB.NET语言的版本:

Imports System.Runtime.InteropServices

Public Class JoyDemoFrm

    Public Const JOY_RETURNBUTTONS = &H80&
  
    Structure JOYINFO
        Dim wXpos As Integer
        Dim wYpos As Integer
        Dim zYpos As Integer
        Dim wButtons As Integer
    End Structure
    Structure JOYINFOEX
        Dim dwSize As Integer   'size of structure 
        Dim dwFlags As Integer   '  flags to indicate what to return 
        Dim wXpos As Integer     '  x position 
        Dim wYpos As Integer     '  y position 
        Dim wZpos As Integer     '  z position 
        Dim wRpos As Integer      '  rudder/4th axis position 
        Dim wUpos As Integer     '  5th axis position 
        Dim wVpos As Integer     '  6th axis position 
        Dim wButtons As Integer '  button states
        Dim wButtonNumber As Integer    '  current button number pressed 
        Dim dwPOV As Integer     '  point of view state 
        Dim dwReserved1 As Integer   '  reserved for communication between winmm driver 
        Dim dwReserved2 As Integer  '  reserved for future expansion 
    End Structure

    Private Declare Function joyGetPos Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef jInfo As JOYINFO) As Integer
    Private Declare Function joyGetPosEx Lib "winmm.dll" (ByVal uJoyID As Integer, ByRef jInfo As JOYINFOEX) As Integer

    Private Sub JoyDemoFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Enabled = True
    End Sub

   

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim infoJEx As JOYINFOEX
        With infoJEx   
            .dwSize = Marshal.SizeOf(GetType(JOYINFOEX))   
            .dwFlags = CInt(JOY_RETURNBUTTONS)  
        End With
        Dim result As Integer = joyGetPosEx(Me.IsDisposed, infoJEx)    '返回JOYERR_NOERROR(值为0)
        'MsgBox(res)
        If result = 0 Then
            '获取成功,输出原始数据
            JoyInfoTXT.Text = "dwSize=" & infoJEx.dwSize & vbCrLf
            JoyInfoTXT.Text &= "dwFlags=" & infoJEx.dwFlags & vbCrLf
            JoyInfoTXT.Text &= "dwXpos =" & infoJEx.wXpos & vbCrLf
            JoyInfoTXT.Text &= "dwYpos =" & infoJEx.wYpos & vbCrLf
            JoyInfoTXT.Text &= "dwZpos =" & infoJEx.wZpos & vbCrLf
            JoyInfoTXT.Text &= "dwRpos=" & infoJEx.wRpos & vbCrLf
            JoyInfoTXT.Text &= "dwUpos=" & infoJEx.wUpos & vbCrLf
            JoyInfoTXT.Text &= "dwVpos=" & infoJEx.wVpos & vbCrLf
            JoyInfoTXT.Text &= "dwButton=" & infoJEx.wButtons & vbCrLf
            JoyInfoTXT.Text &= "dwBNumber=" & infoJEx.wButtonNumber & vbCrLf
            JoyInfoTXT.Text &= "dwPOV=" & infoJEx.dwPOV & vbCrLf
            JoyInfoTXT.Text &= "dwRsved1=" & infoJEx.dwReserved1 & vbCrLf
            JoyInfoTXT.Text &= "dwRsved2=" & infoJEx.dwReserved2 & vbCrLf

            '输出功能数据   
            CurBtn.Text = ""
            If infoJEx.wXpos = 0 Then   '输出左右按键状态
                CurBtn.Text = "左键被按下" & vbCrLf
            ElseIf infoJEx.wXpos = 65535 Then
                CurBtn.Text = "右键被按下" & vbCrLf
            End If
            If infoJEx.wYpos = 0 Then   '输出上下按键状态
                CurBtn.Text &= "上键被按下" & vbCrLf
            ElseIf infoJEx.wYpos = 65535 Then
                CurBtn.Text &= "下键被按下" & vbCrLf
            End If
            '输出数字键
            Dim i As Integer
            For i = 0 To 9  '按位输出
                If (infoJEx.wButtons And 2 ^ i) = 0 Then
                Else
                    CurBtn.Text &= "数字键" & i + 1 & "被按下" & vbCrLf
                End If
            Next
            '输出遥感状态
            '左摇杆
            If (infoJEx.wButtons And 2 ^ 10) Then
                CurBtn.Text &= "左摇杆被按下" & vbCrLf
            End If
            '右遥感
            If (infoJEx.wButtons And 2 ^ 11) Then
                CurBtn.Text &= "右摇杆被按下" & vbCrLf
            End If

            If infoJEx.wZpos < 32511 Then   '位移量
                CurBtn.Text &= "右摇杆状态:" & vbCrLf & "    偏左精度值:" & 32511 - infoJEx.wZpos & vbCrLf
            ElseIf infoJEx.wZpos > 32511 Then
                CurBtn.Text &= "右摇杆状态:" & vbCrLf & "    偏右精度值:" & infoJEx.wZpos - 32511 & vbCrLf
            Else

            End If

            If infoJEx.wRpos < 32511 Then   '位移量
                CurBtn.Text &= "右摇杆状态:" & vbCrLf & "    偏上精度值:" & 32511 - infoJEx.wRpos & vbCrLf
            ElseIf infoJEx.wRpos > 32511 Then
                CurBtn.Text &= "右摇杆状态:" & vbCrLf & "    偏下精度值:" & infoJEx.wRpos - 32511 & vbCrLf
            Else

            End If

        Else
            '获取失败,输出错误
            MsgBox("请确定插上了手柄并且正确安装了驱动")
            End
        End If
    End Sub
End Class


结合后两篇文章对代码中的要点做下总结:

1、此处采用主动方式进行编程,被动方式需要处理冗余的消息包

2、JOYINFO对应joyGetPos方法,获取的参数不全,推荐使用joyGetPosEX函数

3、必须先初始化JOYINFOEX结构实例,并要设置dwSize参数的值,也即是JOYINFOEX结构体所占用的内存空间大小(其值可通过Marshal.SizeOf求得)

4、而如果要取得游戏设备的其它参数,则还必须要设置dwFlags参数的值!否则只能获取坐标值(dwXPos)。如对游戏手柄来说我们需要获取其它按钮的状态,则设置dwFlags的值为JOY_RETURNBUTTONS,用于指示我们需要返回所有按钮的状态。

置于需要进行力反馈编程,据说需要采用DI的方式,而不是API的方式,难道极品中有些版本不支持力反馈也是这个原因?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: