65.9K
CodeProject 正在变化。 阅读更多。
Home

XInputium — 从 XInput 控制器获取输入

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2022年12月10日

MIT

6分钟阅读

viewsIcon

7284

XInputium 简介 — 一个用于 .NET 游戏或应用程序的 XInput 集成的全功能开源库。

引言

当任务是为你的 .NET 应用程序或游戏获取 XInput 兼容设备输入时,你有几种选择。通常,最简单的选择是使用一个提供 XInput 控制器访问权限的库。XInputium 是一个专注于 XInput 的 .NET 库,旨在尽可能简化其使用,同时仍提供强大的功能。在本文中,你将学习如何使用 XInputium 为你的游戏或应用程序添加控制器支持。

什么是 XInputium

XInputium 是一个免费、开源的 .NET 库,它为应用程序提供了访问 XInput 兼容设备的能力。在其 GitHub 存储库中,你可以看到它的实际运行效果,在一个演示应用程序 (XInputium Preview) 中,该应用程序允许用户诊断 XInput 控制器并测试 XInputium 的一些功能。

市面上有很多库为 .NET 应用程序提供 XInput 相关功能。XInputium 有何不同?我将通过提及具体问题来回答这个问题:大多数提供 XInput 功能的库都用于游戏开发,因此它们被从游戏循环中调用,并将大部分输入处理留给你。例如,它们允许你获取控制器的当前状态,但如何处理该状态则取决于你,你需要自己编写代码来检测按键、长按按键、摇杆移动等。

XInputium 的创建就是为了解决这个问题。它的目标是让开发人员编写更少的代码,让库处理大部分与输入相关的逻辑。例如,它允许你检测特定的输入事件,比如当某个按钮被按住一定时间后,或者当摇杆以特定速度向特定方向移动时。XInputium 提供了自动化你在游戏或应用程序中所需的大部分输入逻辑的方法。

在它的功能中,XInputium 也已准备好在 XAML 应用程序中使用。它的属性可以绑定到 XAML,从而更轻松地为应用程序提供开箱即用的 XInput 支持,而不仅仅是游戏。

为了实现其目标,XInputium 使用内部的“输入循环”概念来执行大部分输入处理。你只需要在你的代码中,在每个应用程序或游戏帧调用一个方法;这允许 XInputium 遍历其内部输入循环,并有机会测量时间。内部输入循环使 XInputium 能够比较输入设备状态之间的输入,并提供基于事件的输入处理。它为使用者抽象了许多常见的输入逻辑操作,尽管你仍然可以根据需要使用更底层的访问方式。

开始使用 XInputium

假设你已经有一个应用程序/游戏项目,并且需要允许你的用户通过 XInput 兼容的控制器与你的应用程序/游戏进行交互。

在你的项目中安装 XInputium

你首先需要做的事情,自然是为你的项目添加 XInputium NuGet 包

Install-Package XInputium 

创建你的“Hello world!”

现在你的项目已经设置好了,让我们开始编写代码。从典型的“Hello world!”开始。下面的示例会在用户按下控制器上的任何按钮时,在调试窗口中写入一条消息。显然,你需要连接一个 XInput 兼容的控制器才能使其工作。

“Hello world!” 示例
// Create an 'XGamepad' instance to use across the application.
XGamepad gamepad = new();

// Register an event handler, just for testing. It fires whenever a button is pressed.
// You would usually put this inside your class constructor.
gamepad.ButtonPressed += (s, e) => Debug.WriteLine
        ($"Hello, universe! Button {e.Button} was pressed.");

// Call this on every app/game frame. This will notify XInputium that 
// it can now perform one more iteration on the input loop. Any input 
// events will be fired now.
gamepad.Update();

在前面的示例中,XGamepad 实例代表一个游戏手柄(或游戏控制器),当它被实例化时,它会使用系统中第一个可用的已连接设备(如果存在)。XGamepad 构造函数有多个重载,允许你指定一个设备,甚至不指定任何设备。

gamepad.Update() 方法是所有功能发生的关键。当你调用此方法时,gamepad 实例的状态会使用来自物理设备的最新信息进行更新,其属性会被更新,并且会触发相应的事件。在典型的应用程序或游戏中,你会在每个图形帧调用此方法一次。

使用动态事件

上面的“Hello world!”示例会在按钮被按下时触发一个事件。你可以通过事件参数(即 e.Button)来确定按下了哪个按钮。这很不错,但对于在特定事件发生时触发的事件呢?例如,当某个特定按钮被按住一定时间时?原生的 .NET 事件是固定的——它们不允许我们指定事件如何以及何时触发;更糟糕的是,它们不允许我们在需要时创建新事件。为了解决这个问题,XInputium 提供了动态事件——这些事件参与输入循环,并且仅在满足指定条件时触发。

XInputium 的动态事件是你在 XGamepad 实例中注册的对象实例。这些对象派生自 InputEvent 类。有几个类派生自 InputEvent,每个类代表你可以注册的一种动态事件。例如,DigitalButtonInputEvent 会在指定的按钮被按下、释放或按住时触发,具体取决于你的标准。还有其他动态事件适用于其他任务,例如在用户按住按钮时反复触发(对于菜单和列表很有用),或者根据 lambda 函数执行某些操作,等等。

让我们看看如何注册一个动态事件,该事件在用户按住 **A** 按钮 250 毫秒时触发

XGamepad gamepad = new();

// Subscribe a dynamic event that fires when button A is held for 250ms.
var buttonAHoldEvent = gamepad.RegisterButtonHoldEvent(
    XButtons.A, TimeSpan.FromMilliseconds(250), ButtonHeld);

// Call this on every game/application frame.
gamepad.Update();

// Optionally, unregister the event, later on, when you don't need it anymore.
gamepad.UnregisterInputEvent(buttonAHoldEvent);

// This method will handle the event, just like it would with a regular .NET event.
void ButtonHeld(object? sender, DigitalButtonInputEventArgs<XInputButton> e)
{
    Debug.WriteLine($"Button {e.Button} was held.");
}

在我们刚才看到的示例中,调用了 gamepad.RegisterButtonHoldEvent() 方法来注册动态事件。此方法创建一个 DigitalButtonInputEvent 类的实例,将其注册到输入循环中,将 ButtonHeld() 方法添加为事件处理程序,并返回创建的事件实例(这样你以后可以修改它,使用该实例来注销事件或向其添加更多处理程序)。XGamepad 类有几种方法可以注册特定的动态事件,也有方法可以注册你已经实例化的动态事件。

动态事件允许进行许多非常棒的操作。例如,ActivationInputEvent 类非常通用,它允许你指定一个回调函数,该函数在确定何时触发事件时被调用,并且可以设置多个延迟来指示事件何时以及如何触发。此事件允许进行诸如指示摇杆或扳机何时被移动,同时忽略非常小的移动,或者根据用户按住跳跃按钮的时间长短使游戏角色跳得更高或更低,或者仅在一组按钮同时按下时触发等操作。

文档和进一步阅读

XInputium 具有许多功能。由于本文只是一个介绍,我们只看到了最基本的使用方法,但你可以在其文档中找到更多信息和示例,在 XInputium GitHub 项目的 wiki 部分

XInputium Preview

你还可以查看 XInputium Preview 的源代码,在同一个 GitHub 项目页面。这是演示 XInputium 一些功能的演示应用程序。它是一个 WPF 应用程序,将其 XAML 直接绑定到 XInputium 对象,将大部分输入逻辑留给 XInputium 库。你也可以运行此应用程序来了解 XInputium 的功能。

XInputium Preview

历史

  • 2022 年 12 月 10 日:初版文章发布
© . All rights reserved.