使用 C# 与游戏杆接口






4.76/5 (54投票s)
2006年12月8日
4分钟阅读

614595

30350
一篇关于如何使用 C# 和 Managed DirectX 来操作游戏控制器/操纵杆的文章。

引言
在尝试寻找使用 C# 操作操纵杆的代码时,我发现相关的文章非常少。论坛上有一些零散的代码片段,但没有关于如何使用的完整代码。一个拥有 6 轴、20 多个按钮的操纵杆似乎在之前的 C# 文章中从未出现过,更不用说在 CodeProject 上了。我打算演示如何获取和使用一个完整的 6 轴操纵杆,以及所有可用的按钮。
Managed DirectX
由于 Managed DirectX (MDX) 2.0 尚未发布,并将包含在 XNA 中,因此本文使用 Managed DirectX 1.1,它与 .NET 2.0 完全兼容。但是,您需要在 Visual Studio 2005 中更改一个设置,否则一旦尝试获取设备列表,就会抛出 Loader Lock 异常。在 VS 2005 中,您需要在“调试”菜单下的“异常”中进行更改。在“托管调试助手”中,取消选中“Loader Lock”的“抛出”。这将允许您调试您的应用程序。下载并安装 SDK 后,您可以将引用添加到项目中Microsoft.DirectX.DirectInput
。要使用 Managed DirectX,您必须下载 DirectX 软件开发工具包。在撰写本文时,2006 年 10 月的 SDK 是最新版本。您可以在DirectX SDK 网站下载 SDK。它大约有 500 MB,所以如果您没有快速的网络连接,可能需要一些时间。
查找您的设备
要定位操纵杆,需要获取附加到系统上的所有游戏控制器的列表;DeviceList
方法可以做到这一点。一旦找到设备列表,将获取列表中的第一个控制器。如果您愿意,可以向用户显示控制器列表并允许他们选择正确的控制器。
变量joystickDevice
是一个Device
对象,声明为类的私有成员,它将在后面的其他方法中使用。
// Find all the GameControl devices that are attached.
DeviceList gameControllerList = Manager.GetDevices(DeviceClass.GameControl,
EnumDevicesFlags.AttachedOnly);
// check that we have at least one device.
if (gameControllerList.Count > 0)
{
// Move to the first device
gameControllerList.MoveNext();
DeviceInstance deviceInstance = (DeviceInstance)
gameControllerList.Current;
// create a device from this controller.
joystickDevice = new Device(deviceInstance.InstanceGuid);
joystickDevice.SetCooperativeLevel(this,
CooperativeLevelFlags.Background |
CooperativeLevelFlags.NonExclusive);
}
// Tell DirectX that this is a Joystick.
joystickDevice.SetDataFormat(DeviceDataFormat.Joystick);
// Finally, acquire the device.
joystickDevice.Acquire();
变量joystickDevice
现在应该可以使用了。
操纵杆的功能是什么?
现在可以查询该设备以了解其功能。DeviceCaps
类可以查明操纵杆有多少轴、按钮和 POV 方向键。
// Find the capabilities of the joystick
DeviceCaps cps = joystickDevice.Caps;
// number of Axes
Debug.WriteLine("Joystick Axis: " + cps.NumberAxes);
// number of Buttons
Debug.WriteLine("Joystick Buttons: " + cps.NumberButtons);
// number of PoV hats
Debug.WriteLine("Joystick PoV hats: " + cps.NumberPointOfViews);
当编写实现操纵杆的应用程序时,这些数字可能扮演重要角色。
获取设备输入
每次需要操纵杆的当前状态时,都需要调用Poll
方法来更新joystickDevice
对象。完成后,操纵杆状态将更新,从而可以找到当前的轴位置和按钮状态。以下私有方法将轮询操纵杆并更新状态。此方法更新一个名为state
的JoystickState
对象,它是类中的私有字段。
private void Poll ( )
{
try
{
// poll the joystick
joystickDevice.Poll();
// update the joystick state field
state = joystickDevice.CurrentJoystickState;
}
catch (Exception err)
{
// we probably lost connection to the joystick
// was it unplugged or locked by another application?
Debug.WriteLine(err.Message);
}
}
异常可能需要更智能地处理,但目前不重要。每次我们想从操纵杆检索任何内容时,都需要调用此方法。
一旦为操纵杆的当前状态进行了轮询,就可以从state
对象中检索轴位置和按钮状态。state
对象只有四个轴的属性。下一节演示如何检索六轴操纵杆在使用时可用的最后两个轴。轴的值在 0 到 65535 之间。
int axisA = state.Rz;
int axisB = state.Rx;
int axisC = state.X;
int axisD = state.Y;
state
对象上的GetButtons()
方法返回每个按钮的byte
数组。当值为 128 时,表示按钮已被按下。按钮的读取方式如下:
bool buttonA = buttons[0] >= 128;
您可以对操纵杆的每个按钮执行此操作。此外,POV 方向键也显示在buttons
集合中。
查找其他输入
如果操纵杆有state
对象属性上不可用的额外轴,您可以使用GetSliders
方法来获取另外两个轴。GetSliders
方法返回一个包含两个int
的数组,就像其他轴一样,它们的值从 0 到 65535。
int[] extraAxis = state.GetSlider();
int axisE = extraAxis[0];
int axisF = extraAxis[1];
结论
希望这些信息对您有所帮助,您将能够毫无问题地使用您的操纵杆。本文仅涵盖基本知识,您可能希望实现力反馈或 POV 方向键或其他可用技术。
历史
- 2006 年 12 月 8 日星期五 - 首次发布