按下按钮时的 SlimDx 事件
SlimDx Events on button pressed
我正在使用 slimdx 来解释 xbox 控制器按钮按下。我每 200 毫秒轮询一次以读取 xbox 按钮状态,所有这些都对我有用。我用
JoystickState state = Joystick.GetCurrentState();
// get buttons states
bool[] buttonsPressed = state.GetButtons();
有没有在按下按钮而不是轮询时生成事件的方法?想象一下,如果我的轮询时间是 5 秒。并且用户在第 2 秒按下一个按钮并释放它。在下一次轮询时,我的应用程序永远不会知道按下了按钮
否 - 在 DirectX 中您必须轮询。为了有效地做到这一点,您需要创建一个轮询线程,并有一个 class 将跨线程事件引发到您的消费线程。
我知道这是 4 岁,但答案不正确。最有效的方法可能是轮询,但您可以在轮询时引发事件。
这是一项正在进行的工作,但它应该能让人开始。将其另存为新的 class,它派生自 Timer,因此一旦您将其添加到您的项目、构建它并将其拖到您要使用它的 Form 上,您就可以订阅 buttonPressed 事件。
public class GamePadController : Timer
{
public delegate void ButtonPressedDelegate(object sender, int ButtonNumber);
public event ButtonPressedDelegate ButtonPressed;
List<DeviceInstance> directInputList = new List<DeviceInstance>();
DirectInput directInput = new DirectInput();
List<SlimDX.DirectInput.Joystick> gamepads = new List<Joystick>();
SlimDX.DirectInput.JoystickState state;
public GamePadController()
{
this.Interval = 10;
this.Enabled = true;
this.Tick += GamePadController_Tick;
RefreshGamePads();
}
private void RefreshGamePads()
{
directInputList.Clear();
directInputList.AddRange(directInput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly));
gamepads.Clear();
foreach (var device in directInputList)
{
gamepads.Add(new SlimDX.DirectInput.Joystick(directInput, directInputList[0].InstanceGuid));
}
}
private void GamePadController_Tick(object sender, EventArgs e)
{
foreach (var gamepad in gamepads)
{
if (gamepad.Acquire().IsFailure)
continue;
if (gamepad.Poll().IsFailure)
continue;
if (SlimDX.Result.Last.IsFailure)
continue;
state = gamepad.GetCurrentState();
bool[] buttons = state.GetButtons();
for (int i = 0; i < buttons.Length; i++)
{
if (buttons[i])
{
if (ButtonPressed != null)
{
ButtonPressed(gamepad, i);
}
}
}
gamepad.Unacquire();
}
}
}
}
我正在使用 slimdx 来解释 xbox 控制器按钮按下。我每 200 毫秒轮询一次以读取 xbox 按钮状态,所有这些都对我有用。我用
JoystickState state = Joystick.GetCurrentState();
// get buttons states
bool[] buttonsPressed = state.GetButtons();
有没有在按下按钮而不是轮询时生成事件的方法?想象一下,如果我的轮询时间是 5 秒。并且用户在第 2 秒按下一个按钮并释放它。在下一次轮询时,我的应用程序永远不会知道按下了按钮
否 - 在 DirectX 中您必须轮询。为了有效地做到这一点,您需要创建一个轮询线程,并有一个 class 将跨线程事件引发到您的消费线程。
我知道这是 4 岁,但答案不正确。最有效的方法可能是轮询,但您可以在轮询时引发事件。
这是一项正在进行的工作,但它应该能让人开始。将其另存为新的 class,它派生自 Timer,因此一旦您将其添加到您的项目、构建它并将其拖到您要使用它的 Form 上,您就可以订阅 buttonPressed 事件。
public class GamePadController : Timer
{
public delegate void ButtonPressedDelegate(object sender, int ButtonNumber);
public event ButtonPressedDelegate ButtonPressed;
List<DeviceInstance> directInputList = new List<DeviceInstance>();
DirectInput directInput = new DirectInput();
List<SlimDX.DirectInput.Joystick> gamepads = new List<Joystick>();
SlimDX.DirectInput.JoystickState state;
public GamePadController()
{
this.Interval = 10;
this.Enabled = true;
this.Tick += GamePadController_Tick;
RefreshGamePads();
}
private void RefreshGamePads()
{
directInputList.Clear();
directInputList.AddRange(directInput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly));
gamepads.Clear();
foreach (var device in directInputList)
{
gamepads.Add(new SlimDX.DirectInput.Joystick(directInput, directInputList[0].InstanceGuid));
}
}
private void GamePadController_Tick(object sender, EventArgs e)
{
foreach (var gamepad in gamepads)
{
if (gamepad.Acquire().IsFailure)
continue;
if (gamepad.Poll().IsFailure)
continue;
if (SlimDX.Result.Last.IsFailure)
continue;
state = gamepad.GetCurrentState();
bool[] buttons = state.GetButtons();
for (int i = 0; i < buttons.Length; i++)
{
if (buttons[i])
{
if (ButtonPressed != null)
{
ButtonPressed(gamepad, i);
}
}
}
gamepad.Unacquire();
}
}
}
}