×

用C# 控制游戏设备

Kalet Kalet 发表于2009-03-20 12:00:14 浏览344 评论0

抢沙发发表评论

       在windows中控制游戏设备有现成的通用接口DirectX,不过我今天说的是托管代码的编程方法,不光是C#, VB.net也是适用的。


       首先确保你的操作系统中有DirectX 9 ,在新建项目中添加引用,添加Microsoft.DirectX, Microsoft.DirectX.DirectInput, 添加完成后就可以编写代码了。


       首先罗列出所有的设备,下面的例子用树罗列出了计算机中所有的设备,如果你的手柄连接到了计算机上,你可以看看目录中有没有手柄的名字。

用C# 控制游戏设备

private void PopulateAllDevices(TreeView tvDevices)
{
    
//Add "All Devices" node to TreeView
    TreeNode allNode = new TreeNode("All Devices");
    tvDevices.Nodes.Add(allNode);

    
//Populate All devices
    foreach(DeviceInstance di in Manager.Devices)
    
{

        
//Get Device name
        TreeNode nameNode = new TreeNode(di.InstanceName);

        
//Is device attached?
        TreeNode attachedNode = new TreeNode(
            
"Attached = " + 
            Manager.GetDeviceAttached(di.ProductGuid));

        
//Get device Guid
        TreeNode guidNode = new TreeNode(
            
"Guid = " + di.InstanceGuid);

        
//Add nodes
        nameNode.Nodes.Add(attachedNode);
        nameNode.Nodes.Add(guidNode);
        allNode.Nodes.Add(nameNode);
    }


}

 


上面的例子是罗列出所有设备,如果你只想罗列手柄的话


 



private void PopulateKeyboards(TreeView tvDevices)
{
    
//Add "Keyboard Devices" node to TreeView
    TreeNode keyboardNode = new TreeNode("Keyboard Devices");
    tvInputDevices.Nodes.Add(keyboardNode);

    
//Populate Attached Keyboards
    foreach(DeviceInstance di in
        Manager.GetDevices(DeviceType.Joystick,EnumDevicesFlags.AttachedOnly))
    
{

        
//Get device name
        TreeNode nameNode = new TreeNode(di.InstanceName);
        TreeNode guidNode 
= new TreeNode(
            
"Guid = " + di.InstanceGuid);

        
//Add nodes
        nameNode.Nodes.Add(guidNode);
        keyboardNode.Nodes.Add(nameNode);
    }


}
看看上面两段代码有什么不一样,最主要的地方就是这一句,通过GetDevices方法我们指定了设备的类型

foreach(DeviceInstance di in
        Manager.GetDevices(DeviceType.Joystick,EnumDevicesFlags.AttachedOnly))

让我们来看看都有什么类型,不过有几个我也不知道做什么用的:)。




Keyboard   
Mouse   
Supplemental   
Remote   
ScreenPointer   
DeviceControl   
FirstPerson   
Flight   
Driving   
Gamepad   
Joystick   
Device 
LimitedGameSubtype

如果你想获得有力反馈的设备,用下面的例子。(确保你的设备有驱动哦)


 



private void PopulateForceFeedback(TreeView tvDevices)
{
    
//Add "ForceFeedback Devices" node to TreeView
    TreeNode forcefeedbackNode = new TreeNode("ForceFeedback Devices");
    tvInputDevices.Nodes.Add(forcefeedbackNode);

    
//Populate ForceFeedback Devices
    foreach(DeviceInstance di in
        Manager.GetDevices( DeviceClass.All,EnumDevicesFlags.ForceFeedback))
    
{
        
//Get device name
        TreeNode nameNode = new TreeNode(di.InstanceName);
        nameNode.Tag 
= di;
        TreeNode guidNode 
= new TreeNode("Guid = " + di.InstanceGuid);

        
//Add nodes
        nameNode.Nodes.Add(guidNode);
        forcefeedbackNode.Nodes.Add(nameNode);
    }

}

还是GetDevice方法的使用,这里用到了DeviceClass 和 EnumDevicesFlags.



Member          Value               Description 
Pointer             
2                    All devices of type DI8DEVTYPE_MOUSE and DI8DEVTYPE_SCREENPOINTER. 
Keyboard         
3                    All keyboards. Equivalent to DI8DEVTYPE_KEYBOARD. 
GameControl   
4                    All game controllers. 
Other               
1  用C# 控制游戏设备
All                    
0                    All devices. 

 EnumDevicesFlagsjoystick是个Device 对象,需要在外部声明,这样就获得了你的游戏设备。接着要配置你的设备让他随时准备工作了。下面的InputRange设置游戏设备轴的范围,如果你设置的范围超出了设备的范围,那么程序会自动转换成你设置的范围。



mouse.Properties.AxisModeAbsolute = true;

//Set joystick axis ranges.
foreach(DeviceObjectInstance doi in joystick.Objects)
{
    
if((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)
    
{
        joystick.Properties.SetRange(
            ParameterHow.ById,
            doi.ObjectId,
            
new InputRange(-5000,5000));
    }

}


//Set joystick axis mode absolute.
joystick.Properties.AxisModeAbsolute = true;

//set cooperative level.
keyboard.SetCooperativeLevel(
    
this,
    CooperativeLevelFlags.NonExclusive 
|
    CooperativeLevelFlags.Background);

mouse.SetCooperativeLevel(
    
this,
    CooperativeLevelFlags.NonExclusive 
|
    CooperativeLevelFlags.Background);

joystick.SetCooperativeLevel(
    
this,
    CooperativeLevelFlags.NonExclusive 
|
    CooperativeLevelFlags.Background);

//Acquire devices for capturing.
keyboard.Acquire();
mouse.Acquire();
joystick.Acquire();
最后一步当然就是获得设备的状态了,当你需要知道设备状态的时候使用这些方法就可以了。

[C#]private void UpdateKeyboard()
{
    
string info = "Keyboard: ";

    
//Capture pressed keys.
    foreach(Key k in keyboard.GetPressedKeys())
    
{
        info 
+= k.ToString() + " ";
    }

    lbKeyboard.Text 
= info;
}


private void UpdateMouse()
{
    
string info = "Mouse: ";
                
    
//Get Mouse State.
    MouseState state = mouse.CurrentMouseState;

    
//Capture Position.
    info += "X:" + state.X + " ";
    info 
+= "Y:" + state.Y + " ";
    info 
+= "Z:" + state.Z + " ";

    
//Capture Buttons.
    byte[] buttons = state.GetMouseButtons();
    
for(int i = 0; i < buttons.Length; i++)
    
{
        
if(buttons[i] != 0)
        
{
            info 
+= "Button:" + i + " ";
        }

    }


    lbMouse.Text 
= info;
}


private void UpdateJoystick()
{
    
string info = "Joystick: ";
                
    
//Get Mouse State.
    JoystickState state = joystick.CurrentJoystickState;

    
//Capture Position.
    info += "X:" + state.X + " ";
    info 
+= "Y:" + state.Y + " ";
    info 
+= "Z:" + state.Z + " ";

    
//Capture Buttons.
    byte[] buttons = state.GetButtons();
    
for(int i = 0; i < buttons.Length; i++)
    
{
        
if(buttons[i] != 0)
        
{
            info 
+= "Button:" + i + " ";
        }

    }


    lbJoystick.Text 
= info;
}


用C# 控制游戏设备

 


上面的这些代码是从DirectX SDK 中摘录的,当然SDK中会有更详细的介绍。想看的同志们请下载含有DirectX Documentation for Managemented languages 的版本,我的版本是December 2006的。


群贤毕至

访客