2010-10-14 26 views
16

Ho cercato in giro su Google per questo, ma le uniche cose che ho trovato sono state superate e non ha funzionato.Prendendo input da un joystick con C# .NET

Qualcuno ha qualche informazione su come ottenere i dati del joystick usando C# .NET?

+0

Il ragazzo che ha scritto che è un mio amico. Dice che non funzionerà con il moderno .NET. Sto parlando con lui su IM in questo momento. – chris12892

+0

Non ho mai programmato un joystick come dispositivo di interfaccia, ma la mia comprensione di utente è che il joystick controlla la mappa per i controlli di tastiera e mouse (ad esempio: quando configuro il controller logitech USB PS2 per HL2, mappo ciascun pulsante su il controller di un tasto o il pulsante del mouse) –

+0

Ironicamente, 5 anni dopo, quando ora cerco la stessa domanda, trovo questa domanda che menziona obsoleto e non funziona: | – Spiked3

risposta

12

uno: usare SlimDX.

Due: assomiglia a questo (dove GamepadDevice è il mio involucro e il codice è ridotto solo alle parti pertinenti).

Trova i 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 volta che l'utente ha selezionato dall'elenco, acquisire il 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(); 
    } 

Polling il pad si presenta così:

 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

Mentre le persone stanno ancora leggendo questa risposta, dovrei notare che in seguito sono passato a RawInput: http://stackoverflow.com/a/12988935/184998 –

+0

la parte fino ad acquisire opere per me finora, ho fatto saltare la cooperativa set chiamata di livello. Sono su Windows 7. Risposte altrove su SO dire che Microsoft consiglia di utilizzare RawInput invece di DirectInput – Maslow

4

La cattiva notizia è che Microsoft sembra smettere di supportare le loro librerie NET per DirectX e si concentra invece su XNA. Non lavoro in GameDev quindi non ho bisogno di usare XNA, ma puoi provare se sviluppi giochi per computer. La buona notizia è che ci sono altri approcci. Uno è SlimDX il nuovo framework per aiutarti a wok con DirectX da C#. L'altro modo è aggiungere direttamente riferimenti a "Microsoft.DirectX.dll" e "Microsoft.DirectX.DirectInput.dll" al progetto. li puoi trovare ".. \ Windows \ Microsoft.NET \ DirectX per codice gestito \". se hai intenzione di utilizzare l'ultimo approccio, ecco un link to codeproject in cui puoi leggere come lavorare con un joystick.

MODIFICA: Se l'applicazione è basata sulla versione NET più recente, 2.0 l'applicazione potrebbe bloccarsi. Per risolvere questo problema file di configurazione cambiamento e aggiungere questo:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
22

Dato che questo è stato il colpo più alto che ho avuto su google durante la ricerca di input joystick/gamepad in C#, ho pensato Dovrei pubblicare una risposta per far vedere agli altri.

Il modo più semplice che ho trovato era usare SharpDX e DirectInput. È possibile installarlo tramite NuGet (SharpDX.DirectInput)

Dopo di che, è semplicemente una questione di chiamare alcuni metodi:

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

Spero che questo aiuta.

Ho persino ottenuto questo funzionamento con un driver DualShock3 e MotioninJoy.

+0

Questo è il più semplice da implementare. Grazie per questo! –

0

Google mi ha portato qui e pur non essendo un requisito di questa domanda, OpenTK è una buona opzione per il supporto di Windows e Linux (in mono).

Dal OpenTK docs, questo codice funziona su 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); 
    } 
}