Facebook RSS Feed
 
Windows IoT: USB Gamepad Kullanımı
Tarih: 11.12.2016, Platform: Windows 10 IoT Core, IDE: Visual Studio 2017, Level: 200

Gamepadler elektronik projelerde oyun kavramının önüne geçerek kontrol kolaylığı sağlar. Robot kollarını, kumandalı araçları ve bunun gibi bir çok mekanizmayı gamepad ile kontrol edebilirsiniz. Windows IoT Core, XBox ile çalışan USB ya da kablosuz gamepadleri uygulamanızda kolaylıkla kullanabilmenizi sağlar.

Başlangıç

- Visual Studio ile Visual C# altından Blank App (Universal Windows) uygulaması oluşturun.
- Üst kısımdaki solution platforms menüsünden ARM'ı seçin.
- Solution Explorer'dan References'a sağ tıklayın, Add Reference seçeneğinden Universal Windows > Extensions sekmesi içinden Windows IoT Extensions for the UWP.dll'i seçin. Aynı isimde birden çok dll görünüyorsa versiyonu yüksek olanı seçin.

Uygulama Kodları

Gamepad entegrasyonunu kolaylaştırmak için projenizde GamepadController.cs adında bir class oluşturun.

[C#] GamepadController.cs

// Gamepad Driver for UWP
// Rev. 1.01, Initial Release
// Copyright (c) 2016 Umut Erkal
// www.uerkal.com

using System;
using Windows.Gaming.Input;
using Windows.UI.Xaml;

namespace WinIoTGamepad
{
    #region Events
    // Data for Events
    public class GPAnalogEventArgs : EventArgs
    {
        private double leftStickX, leftStickY, rightStickX,
            rightStickY, leftTrigger, rightTrigger;

        // Constructor
        public GPAnalogEventArgs(double leftStickX, double leftStickY,
            double rightStickX, double rightStickY, double leftTrigger,
            double rightTrigger)
        {
            this.leftStickX = leftStickX;
            this.leftStickY = leftStickY;
            this.rightStickX = rightStickX;
            this.rightStickY = rightStickY;
            this.leftTrigger = leftTrigger;
            this.rightTrigger = rightTrigger;
        }

        public double LeftStickX
        {
            get { return leftStickX; }
        }

        public double LeftStickY
        {
            get { return leftStickY; }
        }

        public double RightStickX
        {
            get { return rightStickX; }
        }

        public double RightStickY
        {
            get { return rightStickY; }
        }

        public double LeftTrigger
        {
            get { return leftTrigger; }
        }

        public double RightTrigger
        {
            get { return rightTrigger; }
        }
    }

    public class GPButtonEventArgs : EventArgs
    {
        public enum Buttons
        {
            A,
            B,
            X,
            Y,
            Back,
            Menu,
            View,
            LeftShoulder,
            RightShoulder,
            LeftThumbstick,
            RightThumbstick,
            DpadUp,
            DpadDown,
            DpadLeft,
            DpadRight,
            Paddle1,
            Paddle2,
            Paddle3,
            Paddle4
        }

        private Buttons button;
        private bool buttonState;

        // Constructor
        public GPButtonEventArgs(Buttons button, bool buttonState)
        {
            this.button = button;
            this.buttonState = buttonState;
        }

        public Buttons Button
        {
            get { return button; }
        }

        public bool ButtonState
        {
            get { return buttonState; }
        }
    }
    #endregion

    public class GamepadController
    {
        Gamepad gp = null;
        GamepadReading gr;
        DispatcherTimer timer;
        private bool btnA = false, btnB = false, btnX = false, btnY = false;
        private bool pBtnA = false, pBtnB = false, pBtnX = false, pBtnY = false;
        private double leftStickX, leftStickY, rightStickX,
            rightStickY, leftTrigger, rightTrigger;

        public GamepadController()
        {
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(50);
            timer.Tick += GPReadTimerTick;
            timer.Start();

            Gamepad.GamepadAdded += Gamepad_GamepadAdded;
            Gamepad.GamepadRemoved += Gamepad_GamepadRemoved;
        }
        private void Gamepad_GamepadAdded(Object sender, Gamepad e)
        {
            gp = e;
        }

        private void Gamepad_GamepadRemoved(Object sender, Gamepad e)
        {
            gp = null;
        }

        private void GPReadTimerTick(object sender, object e)
        {
            if (gp != null)
            {
                gr = gp.GetCurrentReading();

                leftStickX = gr.LeftThumbstickX;
                leftStickY = gr.LeftThumbstickY;
                rightStickX = gr.RightThumbstickX;
                rightStickY = gr.RightThumbstickY;
                leftTrigger = gr.LeftTrigger;
                rightTrigger = gr.RightTrigger;

                AnalogChange(leftStickX, leftStickY, rightStickX,
                    rightStickY, leftTrigger, rightTrigger);

                btnA = (gr.Buttons & GamepadButtons.A) == GamepadButtons.A;
                btnB = (gr.Buttons & GamepadButtons.B) == GamepadButtons.B;
                btnX = (gr.Buttons & GamepadButtons.X) == GamepadButtons.X;
                btnY = (gr.Buttons & GamepadButtons.Y) == GamepadButtons.Y;


                if (btnA != pBtnA)
                {
                    ButtonChange(GPButtonEventArgs.Buttons.A, btnA);
                }

                if (btnB != pBtnB)
                {
                    ButtonChange(GPButtonEventArgs.Buttons.B, btnB);
                }

                if (btnX != pBtnX)
                {
                    ButtonChange(GPButtonEventArgs.Buttons.X, btnX);
                }

                if (btnY != pBtnY)
                {
                    ButtonChange(GPButtonEventArgs.Buttons.Y, btnY);
                }

                pBtnA = (gr.Buttons & GamepadButtons.A) == GamepadButtons.A ? true : false;
                pBtnB = (gr.Buttons & GamepadButtons.B) == GamepadButtons.B ? true : false;
                pBtnX = (gr.Buttons & GamepadButtons.X) == GamepadButtons.X ? true : false;
                pBtnY = (gr.Buttons & GamepadButtons.Y) == GamepadButtons.Y ? true : false;
            }
        }


        // Delegate Decleration
        public delegate void GPAnalogEventHandler(object sender, GPAnalogEventArgs e);
        public delegate void GPButtonEventHandler(object sender, GPButtonEventArgs e);

        public void AnalogChange(double leftStickX, double leftStickY,
            double rightStickX, double rightStickY, double leftTrigger, double rightTrigger)
        {
            // Fire the event
            GPAnalogEventArgs ea = new GPAnalogEventArgs(leftStickX, leftStickY, rightStickX,
                rightStickY, leftTrigger, rightTrigger);
            OnAnalogChanged(ea);
        }

        public void ButtonChange(GPButtonEventArgs.Buttons button, bool state)
        {
            // Fire the event
            GPButtonEventArgs ea = new GPButtonEventArgs(button, state);
            OnButtonChanged(ea);
        }

        #region Events
        public event GPAnalogEventHandler AnalogChanged;
        public event GPButtonEventHandler ButtonChanged;

        protected virtual void OnAnalogChanged(GPAnalogEventArgs e)
        {
            GPAnalogEventHandler handler = AnalogChanged;
            if (handler != null) handler(this, e);
        }

        protected virtual void OnButtonChanged(GPButtonEventArgs e)
        {
            GPButtonEventHandler handler = ButtonChanged;
            if (handler != null) handler(this, e);
        }
        #endregion
    }
}

Bu sınıf saniyede 20 kez gamepad değerlerini alarak değişim durumunda event oluşturacaktır. Timer intervalini 50ms'den istediğiniz değerle değiştirerek yenilenme oranını kontrol edebilirsiniz.

Şimdi uygulamanızın mantığını yazacağınız MainPage.xaml.cs dosyasını açın ve aşağıdaki kodları ekleyin:

using System;
using Windows.UI.Xaml.Controls;

namespace WinIoTGamepad
{
    public sealed partial class MainPage : Page
    {
        // Gamepad'i tanımla
        GamepadController gp;

        public MainPage()
        {
            this.InitializeComponent();

            // Gamepad'i başlat
            gp = new GamepadController();

            // Stick değişme event handler'ı oluştur
            gp.AnalogChanged += AnalogChanged;

            // Buton değişme event handler'ı oluştur
            gp.ButtonChanged += ButtonChanged;
        }

        private void AnalogChanged(Object sender, GPAnalogEventArgs e)
        {
            // Analog değerleri
            double lsX = e.LeftStickX;
            double lsR = e.LeftStickY;
            double rsX = e.RightStickX;
            double rsR = e.RightStickY;
            double lt = e.LeftTrigger;
            double rt = e.RightTrigger;
        }

        private void ButtonChanged(Object sender, GPButtonEventArgs e)
        {
            bool btnSt = false;

            // Buton durumları
            switch (e.Button)
            {
                case GPButtonEventArgs.Buttons.A:
                    btnSt = e.ButtonState;
                    break;
                case GPButtonEventArgs.Buttons.B:
                    btnSt = e.ButtonState;
                    break;
                case GPButtonEventArgs.Buttons.X:
                    btnSt = e.ButtonState;
                    break;
                case GPButtonEventArgs.Buttons.Y:
                    btnSt = e.ButtonState;
                    break;
                default:
                    break;
            }
        }
    }
}

AnalogChanged ve ButtonChanged eventleri gamepad durumunu raporlayacaktır.

Bu uygulamayı hem Windows IoT Core'da hem de normal Windows sürümü ile masaüstü bilgisayarınızda kullanabilirsiniz.


Ek Dosya: Belirtilmemiş.
Okunma Sayısı: 1087

comments powered by Disqus
 
Hoşgeldiniz!
Son güncelleme: 25.12.2016
-
Yeni Teknik Yazılar
Latte Panda İncelemesi
Turta IoT HAT İncelemesi
USB Gamepad Kullanımı
GPIO Kullanımı
VEML6075 UV Sensör Kullan...
-
İlgili Gruplar
.NET MF ve Gadgeteer FB Grubu
İst. IoT & Wearables Meet-up
-
 

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.Copyright © 1999 - 2017, Umut Erkal. Bu materyal, "Creative Commons Public Licence" ile sunulmuştur.
Kaynak göstererek ve ücretsiz olarak, aynı şartlar altında paylaşabilir ve kullanabilirsiniz. | Kullanım Sözleşmesi