【问题标题】:Gamepad PoV control going to sleep游戏手柄 PoV 控制进入睡眠状态
【发布时间】:2018-11-05 14:32:51
【问题描述】:

当轮询我的游戏手柄并且它在一两分钟内什么都不做时,PoV 控件进入某种睡眠模式并且不返回任何内容,但选择了一个按钮将其唤醒。这是正常的吗?有没有办法让 PoV 不睡觉?

复选框激活....

  private void CheckBoxJoystick_Checked(object sender, EventArgs e)
    {
        if (CheckboxJoystick.IsChecked.HasValue & CheckboxJoystick.IsChecked == true)
        {
            var windowHandle = Process.GetCurrentProcess().MainWindowHandle;
            _gamepad = new Gamepad(windowHandle);
            if (!_gamepad.IsAvailable) return;
            ctsGamepad?.Cancel();
            ctsGamepad = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(DoGamepadWork, ctsGamepad.Token);
        }
    }

轮询游戏手柄的主循环...

  private void DoGamepadWork(object obj)
    {
        if (!_gamepad.IsAvailable) return;
        var token = (CancellationToken)obj;
        var buttontocheck = -1;
        var povtocheck = new PovPair(-1,0);
        while (true)
        {
            if (token.IsCancellationRequested)
            {
                break;
            }
            _gamepad.Poll();
            // Check buttons...
            // Check PoVs...
            Thread.Sleep(100);
        }
    }

轮询游戏手柄....

    public void Poll()
    {
        try
        {
            if (!IsAvailable) return;
            joystick.Acquire();
            joystick.Poll();
            State = joystick.GetCurrentState();
            Buttons = State.Buttons;
            Povs = State.PointOfViewControllers;
            Datas = joystick.GetBufferedData();
        }
        catch(Exception ex)
        {            }
    }

找到附加的游戏手柄...

    private void Find()
    {
        foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, DeviceEnumerationFlags.AttachedOnly))
            joystickGuid = deviceInstance.InstanceGuid;

        // If Gamepad not found, look for a Joystick
        if (joystickGuid == Guid.Empty)
            foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AttachedOnly))
                joystickGuid = deviceInstance.InstanceGuid;

        // If Joystick not found
        if (joystickGuid == Guid.Empty)
        {
            IsAvailable = false;
            return;
        }

        // Instantiate the joystick
        joystick = new Joystick(directInput, joystickGuid);
        joystick.SetCooperativeLevel(hWnd, CooperativeLevel.Background | CooperativeLevel.NonExclusive);

        // Set BufferSize in order to use buffered data.
        joystick.Properties.BufferSize = 128;

        // Acquire the joystick
        joystick.Acquire();
        IsAvailable = true;
        Load_Settings();
    }

【问题讨论】:

  • 我们能看到全局循环吗,也许你阻止了你的用户界面?通常获取只进行一次,或者如果获取丢失..
  • 修改原帖,放入主逻辑。不阻塞 UI 并且状态在唤醒之前不会报告任何 PoV 数据。就收购而言。我只做了一次,并且会时不时地得到一个未获得的错误,每次都这样做会阻止它,但不确定它是否会导致这个问题。我认为这不是问题,因为按钮一直都在工作。 -- 谢谢
  • 抱歉,我没有看到您用于游戏手柄的框架?直接输入,xna?你能准确吗
  • SharpDX.DirectInput;
  • 好的,你能显示 Gamepad 类吗,我想知道你是如何枚举控制器的,你正在使用的合作级别......

标签: c# wpf sharpdx joystick gamepad


【解决方案1】:

它是一个功能示例,我选择了第一个棒...按钮 0 停止循环并测试 pov[0]

using SharpDX.DirectInput;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            var controller = new Controller();
        }
    }

    public class Controller
    {
        private Task pollingTask;
        private bool running;

        private JoystickState state;

        public JoystickState State => state ?? (state = controller.GetCurrentState());
        public Joystick controller;
        public Controller()
        {
            var directInput = new DirectInput();
            var handle = Process.GetCurrentProcess().MainWindowHandle;
            var diDevices = directInput.GetDevices(DeviceClass.GameControl, DeviceEnumerationFlags.AttachedOnly);
            controller = new Joystick(directInput, diDevices[0].InstanceGuid);
            controller.SetCooperativeLevel(handle, CooperativeLevel.Exclusive | CooperativeLevel.Background);
            controller.Acquire();
            running = true;
            PollJoystick();

            if (pollingTask != null)
            {
                pollingTask.Wait();
            }
            Console.WriteLine("fini");
            Console.ReadKey();
        }
        TimeSpan period = TimeSpan.FromMilliseconds(30);
        public int[] Pov => State.PointOfViewControllers;
        public bool stop => State.Buttons[0];
        public void PollJoystick()
        {
            pollingTask = Task.Factory.StartNew(() => {
                while (running)
                {
                    state = null;
                    running = !stop;
                    if (Pov[0] != -1)
                        Console.WriteLine(Pov[0]);
                    Task.Delay(period);
                }
            });
        }
    }
}

【讨论】:

  • 谢谢,我确实将我所拥有的转换为 Task.Run(() 但 pov 和轴仍然会休眠。不确定这是否能解决这个问题,但我会试试看.
  • 如果你使用我的程序,你有同样的事情吗?
  • 我发现我拥有的 gampepad 确实有睡眠模式,但你的回答对于你处理状态和没有轮询的方式非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多