Facebook RSS Feed
 

C#: USB Gamepad Bağlantısı (XNA Framework)

-Bir Windows Forms uygulamasına gamepad entegre etmenin başka bir yolu da XNA Framework kullanmaktır. XNA Framework ile Direct Input metoduna göre daha fonksiyonel bir uygulama geliştirebiliriz. XNA Framework ile geliştirdiğimiz uygulama yalnızca XBOX uyumlu gamepadler (Orjinal XBOX Gamepadleri yada Logitech ChillStream vs...) ile çalışacaktır. Diğer gamepadleri kullanmak istiyorsanız, Direct Input yöntemini anlatan yazımı okuyabilirsiniz.

-

Ön Gereksinimler

XNA Framework ile gamepad uygulaması geliştirmek için bilgisayarınıza XNA Game Studio'nun kurulu olması gerekiyor. Değilse 3.1 sürümünü Microsoft Download Center'dan yükleyebilirsiniz. C# ile yeni bir Windows Forms uygulaması oluşturarak işe koyulalım...

64 Bit Makineler İçin Proje Ayarları

32 Bit Windows kullanıyorsanız Uygulama Kodları başlığına atlayabilirsiniz.

64 Bit Windows kullanıyorsanız, XNA Framework ile çalışmak için Visual Studio debug ve build ayarlarını x86 platformuna göre ayarlamanız gerekiyor. Bunun için, Visual Studio'nun Tools menüsünden Options penceresini açıp sol alttaki Show All Settings'i seçin. Daha sonra yine Options penceresinden Projects & Solutions başlığı altındaki Show Advanced Build Configurations seçeneğini aktif hale getirin.

-

Şimdi, Build menüsünden Configuration Manager'ı seçip Platform seçeneğiini x86 olarak ayarlayın.

-

Son olarak, .NET 4 kullanıyorsanız projenizi XNA Framework ile uyumlu hale getirmek için Solution Explorer'dan Add > New Item'ı seçip app.config adında bir Application Configuration File oluşturup içeriğini aşağıdaki gibi değiştirin.

<?xml version="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0"/>
  </startup>
</configuration>

Yaptığımız ayarlarla projemiz XNA Framework ile uyumlu çalışacak hale geldi.

Uygulama Kodları

Proje referanslarına Microsoft.Xna.Framework ve Microsoft.Xna.Framework.Game'i ekleyelim. Daha sonra namespace'lere aşağıdaki satırları ekleyelim:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

Gamepadin anlık durumunu (Buton ve analog durumu  gibi) saklayacak bir GamePadState değişkeni oluşturacağız. XNA ile 4'e kadar gamepad bağlantısı yapabileceğimiz için, o an hangi gamepadin aktif olduğunu belirten PlayerIndex değişkenini de global olarak tanımlayalım:

GamePadState gmDurum;
PlayerIndex gmIndex;

Formun tasarımında aktif gamepadi seçmek için bir ComboBox ekledik. Başlangıçta ComboBox'ın seçili indexini 0 olarak ayarlayalım ve saniyede 50 kez gamepad durumunu sorgulayacak bir timer oluşturalım:

private void frmGamepadXNA_Load(object sender, EventArgs e)
{
  cmbPlayerIndex.SelectedIndex = 0; //Aktif gamepad
  Timer tmr = new Timer();          //Gamepad durumunu sorgulayacak timer
  tmr.Enabled = true;
  tmr.Interval = 20;                //Gamepadin sorgulanma hassasiyeti.
                                    //İhtiyacınıza göre arttırıp azaltabilirsiniz.
  tmr.Tick += new EventHandler(tmr_Tick);
  tmr.Start();
}

Gamepad seçim ComboBox'ının değerini değiştirdiğimizde o anki player indexini ayarlamak için ComboBox Selected Item Changed eventine aşağıdaki kodları ekleyelim:

private void cmbPlayerIndex_SelectedIndexChanged(object sender, EventArgs e)
{
  switch (cmbPlayerIndex.SelectedIndex)
  {
    case 0: gmIndex = PlayerIndex.One; break;
    case 1: gmIndex = PlayerIndex.Two; break;
    case 2: gmIndex = PlayerIndex.Three; break;
    case 3: gmIndex = PlayerIndex.Four; break;
    default: break;
  }
}

Şimdi ise saniyede 50 defa gamepadin durumunu sorgulayacak ve o anki değerleri forma yansıtacak timer tick metodunu yazalım:

void tmr_Tick(object sender, EventArgs e)
{
  //Seçili gamepadin durumunu sorgulayıp, tüm parametreleri gmDurum değişkenine atayalım:
  gmDurum = GamePad.GetState(gmIndex);

  //Gamepad bağlantısının durumunu PicrureBox içinde gösterelim:
  if (gmDurum.IsConnected) pbBaglanti.Image = Properties.Resources.Green;
  else pbBaglanti.Image = Properties.Resources.Red;

  //Butonların durumunu CheckBox'lara atayalım:
  cbButonA.Checked = (gmDurum.Buttons.A == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonB.Checked = (gmDurum.Buttons.B == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonX.Checked = (gmDurum.Buttons.X == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonY.Checked = (gmDurum.Buttons.Y == Microsoft.Xna.Framework.Input.ButtonState.Pressed);

  //Pedal Butonları
  cbButonLB.Checked =
    (gmDurum.Buttons.LeftShoulder == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonRB.Checked =
    (gmDurum.Buttons.RightShoulder == Microsoft.Xna.Framework.Input.ButtonState.Pressed);

  //Analog Butonları
  cbButonLA.Checked = (gmDurum.Buttons.LeftStick == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonRA.Checked =
    (gmDurum.Buttons.RightStick == Microsoft.Xna.Framework.Input.ButtonState.Pressed);

  //Start ve Back Butonları
  cbButonStart.Checked = (gmDurum.Buttons.Start == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbButonBack.Checked = (gmDurum.Buttons.Back == Microsoft.Xna.Framework.Input.ButtonState.Pressed);

  //D Pad
  cbDPadUp.Checked = (gmDurum.DPad.Up == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbDPadDown.Checked = (gmDurum.DPad.Down == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbDPadLeft.Checked = (gmDurum.DPad.Left == Microsoft.Xna.Framework.Input.ButtonState.Pressed);
  cbDPadRight.Checked = (gmDurum.DPad.Right == Microsoft.Xna.Framework.Input.ButtonState.Pressed);

  //Analoglar
  lblXAxis.Text = "%" + (gmDurum.ThumbSticks.Left.X * 100).ToString();
  lblYAxis.Text = "%" + (gmDurum.ThumbSticks.Left.Y * 100).ToString();
  lblXRotation.Text = "%" + (gmDurum.ThumbSticks.Right.X * 100).ToString();
  lblYRotation.Text = "%" + (gmDurum.ThumbSticks.Right.Y * 100).ToString();

  //Pedallar
  lblLeftTrigger.Text = "%" + (gmDurum.Triggers.Left * 100).ToString();
  lblRightTrigger.Text = "%" + (gmDurum.Triggers.Right * 100).ToString();
}

Titreşim butonuna tıklandığında, o an seçili gamepadin titreşim motorlarına 0 ile 1 arasında parametre göndereceğiz. Sol motor düşük, sağ motor ise yüksek frekansta titreşim üretir.

private void btnVibrate_Click(object sender, EventArgs e)
{
  GamePad.SetVibration(gmIndex, (float)numSol.Value, (float)numSag.Value);
}

Uygulamayı kapatırken motorların durdurulması için az sonra tanımlayacağımız TitreşimiDurdur metodunu çağıralım:

private void frmGamepadXNA_FormClosing(object sender, FormClosingEventArgs e)
{
  TitresimiDurdur();
}

Bağlı tüm gamepadlerin titreşimlerini durduracak metodu da ekleyerek uygulamamızın kodlarını tamamlıyoruz.

private void TitresimiDurdur()
{
  GamePad.SetVibration(PlayerIndex.One, 0.0f, 0.0f);
  GamePad.SetVibration(PlayerIndex.Two, 0.0f, 0.0f);
  GamePad.SetVibration(PlayerIndex.Three, 0.0f, 0.0f);
  GamePad.SetVibration(PlayerIndex.Four, 0.0f, 0.0f);
}

Uygulamayı çalıştırdığınızda "Could not load file or assembly 'Microsoft.Xna.Framework, Version=2.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d' or one of its dependencies. An attempt was made to load a program with an incorrect format." hatasını alırsanız, 64 Bit Makineler İçin Proje Ayarları başlığındaki ayarlara göz atın.

Uygulamanın kaynak kodlarını buradan indirebilirsiniz.




 
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