web-dev-qa-db-fra.com

Prendre une entrée d'une manette de jeu avec C # .NET

J'ai cherché cela sur Google, mais les seules choses que j'ai trouvées étaient dépassées et ne fonctionnaient pas.

Quelqu'un at-il des informations sur la manière d'obtenir des données de manette de jeu en utilisant C # .NET?

18
chris12892

One: utilisez SlimDX .

Deux: cela ressemble à quelque chose comme ceci (où GamepadDevice est mon propre wrapper, et le code est réduit aux seules parties pertinentes). 

Recherchez les GUID du joystick/pad:

    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;
    }

Une fois l’utilisateur sélectionné dans la liste, procurez-vous le gamepad:

   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();
    }

Interroger le pad ressemble à ceci:

        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();
13
Adrian Cox

Etant donné que c’était le meilleur hit que j’ai eu sur Google lors de mes recherches sur les entrées de manette de jeu/manette de jeu en C #, j’ai pensé que je devrais poster une réponse à l’intention des autres.

Le moyen le plus simple que j'ai trouvé était d'utiliser SharpDX et DirectInput. Vous pouvez l'installer via NuGet (SharpDX.DirectInput)

Après cela, il suffit simplement d’appeler quelques méthodes:

Exemple de code 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);
    }
}

J'espère que ça aide.

J'ai même eu cela pour travailler avec un DualShock3 et les pilotes MotioninJoy.

25
Valdemar

La mauvaise nouvelle est que Microsoft semble cesser de prendre en charge ses bibliothèques NET pour DirectX et se concentrer sur XNA. Je ne travaille pas sur GameDev, je n'ai donc pas besoin d'utiliser XNA, mais vous pouvez l'essayer si vous développez des jeux sur ordinateur. La bonne nouvelle est qu’il existe d’autres approches. Le premier est SlimDX le nouveau cadre qui vous aidera à utiliser DirectX à partir de C #. L’autre méthode consiste à ajouter directement les références de "Microsoft.DirectX.dll" et "Microsoft.DirectX.DirectInput.dll" à votre projet. vous pouvez les trouver "..\Windows\Microsoft.NET\DirectX pour le code géré \". si vous allez utiliser la dernière approche, voici un lien vers codeproject où vous pouvez lire comment utiliser un joystick. 

EDIT: Si votre application est basée sur une version NET plus récente que la version 2.0, elle risque de s’arrêter. Pour résoudre ce problème, changez le fichier de configuration et ajoutez ceci:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
4
Arseny

Google m'a conduit ici et bien que ce ne soit pas une exigence de cette question, OpenTK est une bonne option pour le support Windows et Linux (sous mono).

Depuis la documentation OpenTK , ce code fonctionne sur 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);
    }
}
0
fiat