Получение ввода с джойстика с C # .NET - PullRequest
18 голосов
/ 14 октября 2010

Я искал в Google это, но единственные вещи, которые я придумал, были устаревшими и не работали.

У кого-нибудь есть какая-либо информация о том, как получить данные джойстика с помощью C # .NET?

Ответы [ 4 ]

25 голосов
/ 06 декабря 2012

Так как это был лучший хит, который я получил в Google при исследовании ввода джойстика / геймпада в C #, я подумал, что должен опубликовать ответ, чтобы другие могли его увидеть.

Самый простой способ, который я нашел, - это использовать SharpDX иПрямой ввод.Вы можете установить его через NuGet (SharpDX.DirectInput)

После этого достаточно просто вызвать несколько методов:

Пример кода из SharpDX

static void Main()
{
    // Initialize DirectInput
    var directInput = new DirectInput();

    // Find a Joystick Guid
    var joystickGuid = Guid.Empty;

    foreach (var deviceInstance in directInput.GetDevices(DeviceType.Gamepad, 
                DeviceEnumerationFlags.AllDevices))
        joystickGuid = deviceInstance.InstanceGuid;

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

    // If Joystick not found, throws an error
    if (joystickGuid == Guid.Empty)
    {
        Console.WriteLine("No joystick/Gamepad found.");
        Console.ReadKey();
        Environment.Exit(1);
    }

    // Instantiate the joystick
    var joystick = new Joystick(directInput, joystickGuid);

    Console.WriteLine("Found Joystick/Gamepad with GUID: {0}", joystickGuid);

    // Query all suported ForceFeedback effects
    var allEffects = joystick.GetEffects();
    foreach (var effectInfo in allEffects)
        Console.WriteLine("Effect available {0}", effectInfo.Name);

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

    // Acquire the joystick
    joystick.Acquire();

    // Poll events from joystick
    while (true)
    {
        joystick.Poll();
        var datas = joystick.GetBufferedData();
        foreach (var state in datas)
            Console.WriteLine(state);
    }
}

Надеюсь, это поможет.

Я даже заставил это работать с драйверами DualShock3 и MotioninJoy.

13 голосов
/ 09 марта 2011

Один: используйте SlimDX .

Два: это выглядит примерно так (где GamepadDevice - моя собственная оболочка, а код уменьшен до соответствующих частей).

Найдите GUID джойстика / пэда:

    public virtual IList<GamepadDevice> Available()
    {
        IList<GamepadDevice> result = new List<GamepadDevice>();
        DirectInput dinput = new DirectInput();
        foreach (DeviceInstance di in dinput.GetDevices(DeviceClass.GameController, DeviceEnumerationFlags.AttachedOnly))
        {
            GamepadDevice dev = new GamepadDevice();
            dev.Guid = di.InstanceGuid;
            dev.Name = di.InstanceName;
            result.Add(dev);
        }
        return result;
    }

Как только пользователь выбрал из списка, приобретите геймпад:

   private void acquire(System.Windows.Forms.Form parent)
    {
        DirectInput dinput = new DirectInput();

        pad = new Joystick(dinput, this.Device.Guid);
        foreach (DeviceObjectInstance doi in pad.GetObjects(ObjectDeviceType.Axis))
        {
            pad.GetObjectPropertiesById((int)doi.ObjectType).SetRange(-5000, 5000);
        }

        pad.Properties.AxisMode = DeviceAxisMode.Absolute;
        pad.SetCooperativeLevel(parent, (CooperativeLevel.Nonexclusive | CooperativeLevel.Background));
        pad.Acquire();
    }

Опрос панели выглядит следующим образом:

        JoystickState state = new JoystickState();

        if (pad.Poll().IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        if (pad.GetCurrentState(ref state).IsFailure)
        {
            result.Disconnect = true;
            return result;
        }

        result.X = state.X / 5000.0f;
        result.Y = state.Y / 5000.0f;
        int ispressed = 0;
        bool[] buttons = state.GetButtons();
4 голосов
/ 09 марта 2011

Плохая новость заключается в том, что Microsoft, похоже, перестала поддерживать свои NET-библиотеки для DirectX и вместо этого сосредоточилась на XNA.Я не работаю в GameDev, поэтому мне не нужно использовать XNA, но вы можете попробовать его, если разрабатываете компьютерные игры.Хорошей новостью является то, что есть и другие подходы.Один из них - SlimDX - новый фреймворк, который поможет вам работать с DirectX из C #.Другой способ - добавить ссылки «Microsoft.DirectX.dll» и «Microsoft.DirectX.DirectInput.dll» в ваш проект.Вы можете найти их ".. \ Windows \ Microsoft.NET \ DirectX для управляемого кода \".Если вы собираетесь использовать последний подход, то здесь есть ссылка на кодовый проект , где вы можете прочитать, как работать с джойстиком.

РЕДАКТИРОВАТЬ: Если ваше приложение основано на версии NET более новой, чем 2.0, приложение может зависнуть.Чтобы решить эту проблему, измените файл конфигурации и добавьте:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
0 голосов
/ 14 февраля 2015

Google привел меня сюда, и хотя этот вопрос не является обязательным, OpenTK является хорошим вариантом для поддержки Windows и Linux (в режиме моно).

Из документов OpenTK этот код работает на Raspberry Pi + Raspbian + Mono 3.12.0:

for (int i = 0; i < 4; i++)
{
    var state = Joystick.GetState(i);
    if (state.IsConnected)
    {
        float x = state.GetAxis(JoystickAxis.Axis0);
        float y = state.GetAxis(JoystickAxis.Axis1);

        // Print the current state of the joystick
        Console.WriteLine(state);
    }
}
...