在windows中控制游戏设备有现成的通用接口DirectX,不过我今天说的是托管代码的编程方法,不光是C#, VB.net也是适用的。
首先确保你的操作系统中有DirectX 9 ,在新建项目中添加引用,添加Microsoft.DirectX, Microsoft.DirectX.DirectInput, 添加完成后就可以编写代码了。
首先罗列出所有的设备,下面的例子用树罗列出了计算机中所有的设备,如果你的手柄连接到了计算机上,你可以看看目录中有没有手柄的名字。
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 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;}
上面的这些代码是从DirectX SDK 中摘录的,当然SDK中会有更详细的介绍。想看的同志们请下载含有DirectX Documentation for Managemented languages 的版本,我的版本是December 2006的。
