2010-10-14 73 views
16

He buscado en Google para esto, pero las únicas cosas que se me ocurrió fueron obsoletos y no funcionó.Tomando la entrada de un joystick con C# .NET

¿Alguien tiene información sobre cómo obtener datos de joystick usando C# .NET?

+0

El tipo que escribió que es un amigo mío. Él dice que no funcionará con .NET moderno. Estoy hablando con él por mensajería instantánea en este momento. – chris12892

+0

Nunca he programado un joystick como dispositivo de interfaz, pero mi comprensión como usuario es que el joystick controla el mapa de los controles del teclado y el mouse (es decir: cuando configuro el controlador de estilo logitech USB PS2 para HL2, mapeo cada botón el controlador de una tecla o botón del ratón) –

+0

Cómo irónico, 5 años más tarde, cuando ahora google la misma pregunta, me parece que esta pregunta menciona obsoleto y no funciona: | – Spiked3

Respuesta

12

Uno: El uso SlimDX.

Dos: se ve algo como esto (donde GamepadDevice es mi propio envoltorio, y el código se reduce a las partes relevantes).

Encuentra los GUID 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; 
    } 

Una vez que el usuario ha seleccionado de la lista, adquirir el mando de juegos:

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

Polling la almohadilla se ve así:

 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(); 
+1

Como la gente todavía está leyendo esta respuesta, debería tener en cuenta que más tarde cambié a RawInput: http://stackoverflow.com/a/12988935/184998 –

+0

la parte para adquirir trabajos para mí hasta ahora, omití el conjunto cooperativo llamada de nivel Estoy en Windows 7. Responde en otro lugar de SO say Microsoft recomienda que use RawInput en lugar de DirectInput – Maslow

4

La mala noticia es que Microsoft parece dejar de soportar sus bibliotecas NET para DirectX y centrarse en XNA en su lugar. No trabajo en GameDev, así que no necesito usar XNA pero puedes probarlo si desarrollas juegos de computadora. La buena noticia es que hay otros enfoques. Uno es SlimDX el nuevo marco para ayudarlo a trabajar con DirectX desde C#. La otra forma es agregar directamente las referencias de "Microsoft.DirectX.dll" y "Microsoft.DirectX.DirectInput.dll" a su proyecto. puede encontrarlos ".. \ Windows \ Microsoft.NET \ DirectX para Managed Code \". si va a utilizar el último acercamiento aquí hay un enlace to codeproject donde puede leer cómo trabajar con un joystick.

EDIT: Si su aplicación está basada en una versión NET más nueva que la 2.0, la aplicación puede esperar. Para solucionar este problema fichero de configuración de cambio y añadir lo siguiente:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
22

Dado que este fue el mayor éxito que obtuve en google mientras investigaba la entrada de joystick/gamepad en C#, pensé t Debo publicar una respuesta para que otros la vean.

La manera más fácil que encontré fue usar SharpDX y DirectInput. Se puede instalar a través de NuGet (SharpDX.DirectInput)

Después de eso, es simplemente una cuestión de llamar a algunos métodos:

Sample code from 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); 
    } 
} 

espero que esto ayude.

Incluso conseguí que esto funcione con un DualShock3 y los controladores MotioninJoy.

+0

Esta es la forma más fácil de implementar. ¡Gracias por esto! –

0

Google me llevó aquí y aunque no es un requisito de esta pregunta, OpenTK es una buena opción para Windows y Linux (bajo mono).

Desde el OpenTK docs, este código funciona en Frambuesa 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); 
    } 
} 
Cuestiones relacionadas