2010-10-14 33 views
16

Tôi đã tìm kiếm trên Google về điều này, nhưng điều duy nhất tôi đưa ra đã lỗi thời và không hoạt động.Lấy đầu vào từ cần điều khiển bằng C# .NET

Có ai có bất kỳ thông tin nào về cách lấy dữ liệu cần điều khiển bằng C# .NET không?

+0

Anh chàng người viết đó là một người bạn của tôi. Ông nói nó sẽ không hoạt động với .NET hiện đại. Tôi đang nói chuyện với anh ta qua IM ngay bây giờ. – chris12892

+0

Tôi chưa bao giờ lập trình cho phím điều khiển làm thiết bị giao diện, nhưng sự hiểu biết của tôi là người dùng điều khiển bản đồ để điều khiển bàn phím và chuột (ví dụ: khi tôi định cấu hình bộ điều khiển phong cách USB PS2 logitech cho HL2, tôi ánh xạ từng nút trên bộ điều khiển cho một phím hoặc nút chuột) –

+0

Làm thế nào mỉa mai, 5 năm sau, khi tôi bây giờ google cùng một câu hỏi, tôi thấy câu hỏi này đề cập đến lỗi thời và không hoạt động: | – Spiked3

Trả lời

12

Một: sử dụng SlimDX.

Hai: trông giống như thế này (trong đó GamepadDevice là trình bao bọc của riêng tôi và mã được rút gọn xuống chỉ với các phần có liên quan).

Tìm GUIDs phím điều khiển/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; 
    } 

Khi người dùng chọn từ danh sách, tiếp thu các 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 pad trông như thế này:

 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

Vì mọi người vẫn đang đọc câu trả lời này, tôi nên lưu ý rằng sau này tôi chuyển sang RawInput: http://stackoverflow.com/a/12988935/184998 –

+0

một phần để có được công việc cho tôi cho đến nay, tôi đã bỏ qua bộ hợp tác xã gọi cấp. Tôi đang trên cửa sổ 7. câu trả lời ở những nơi khác trên SO nói rằng microsoft khuyến cáo bạn sử dụng RawInput thay vì DirectInput – Maslow

4

Tin xấu là Microsoft dường như ngừng hỗ trợ thư viện NET của họ cho DirectX và tập trung vào XNA thay thế. Tôi không làm việc trong GameDev vì vậy tôi không cần phải sử dụng XNA nhưng bạn có thể thử nó nếu bạn phát triển trò chơi máy tính. Tin tốt là có những cách tiếp cận khác. Một là SlimDX khung công tác mới để giúp bạn chia sẻ với DirectX từ C#. Một cách khác là trực tiếp thêm tài liệu tham khảo của "Microsoft.DirectX.dll" và "Microsoft.DirectX.DirectInput.dll" vào dự án của bạn. bạn có thể tìm thấy chúng ".. \ Windows \ Microsoft.NET \ DirectX cho mã được quản lý \". nếu bạn sẽ sử dụng phương pháp cuối cùng ở đây là một liên kết to codeproject nơi bạn có thể đọc cách làm việc với cần điều khiển.

EDIT: Nếu ứng dụng của bạn dựa trên phiên bản NET mới hơn thì ứng dụng có thể bị treo. Để khắc phục sự cố này, hãy thay đổi tệp cấu hình và thêm tệp này:

<startup useLegacyV2RuntimeActivationPolicy="true"> 
22

Vì đây là hit hàng đầu tôi nhận được trên google trong khi nghiên cứu đầu vào joystick/gamepad trong C#, mặc dù tôi Tôi nên đăng câu trả lời cho người khác xem.

Cách dễ nhất tôi thấy là sử dụng SharpDX và DirectInput. Bạn có thể cài đặt nó qua NuGet (SharpDX.DirectInput)

Sau đó, nó chỉ đơn giản là vấn đề kêu gọi một vài phương pháp:

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

Tôi hy vọng điều này sẽ giúp.

Tôi thậm chí còn làm việc này với trình điều khiển DualShock3 và MotioninJoy.

+0

Đây là cách dễ nhất để thực hiện. Cám ơn vì cái này! –

0

Google đã dẫn tôi đến đây và mặc dù không phải là yêu cầu của câu hỏi này, OpenTK là một tùy chọn tốt cho hỗ trợ Windows và Linux (dưới mono).

Từ OpenTK docs, mã này hoạt động trên 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); 
    } 
} 
Các vấn đề liên quan