Yandex.Metrica
XNA'de Mouse
Merhabalar bu yazımızda XNA'de mouse kontrolleri üzerine örnekler yapacağız.Daha önce ki yazımıda klavye kontrolleri için gerekli ayarlamaları yapmamızın ardından şimdi sıra geldi mouse ayarlarını halletmeye.Hazırladığınız bilgisayar oyunu ağırlıklı olarak mouse kontrolü ile oynanabilen bir oyun olabilir.Onun için XNA Framework bizler için çok kolay bir şekilde kullanabileceğimiz sınıflar sunuyor.Özet olarak bu yazımızda temel mouse işlevlerini projemizde nasıl aktifleştirebileceğimizi,mouse imleci görüntüleme,mouse a tıklandığında tıklanan yeri işaretleme ve bu işaretlenen yere doğru hareket eden denizanası sprite değineceklerimiz.

İlk olarak Game1 sınıfımız içerisinde kullanacağım alanları oluşturarak kodlamamıza başlıyorum.İhtiyaçlarımızı sayarsak iki adet Texture2D,iki adet Vector2,bir adet Bool sınıfından olmak üzere beş adet alan tanımlamamız gerekiyor.Doku sınıfından alanların birisi faremizin imlecini göstermek(1) diğer ise örneğin faremize sol tıkladığımızda ekranda tıklanan yere işaret konulması için gerekli.Vector2 sınıfı değişkenleri ise bu 2D doku sınıfı alanlarımızın çiziminde kullanılacak nokta bilgisi tutacak olan alanlardır.Bool nesnemiz ise faremize sol tık yaptığımızda bize haber verecek diğer zamanlarda false olarak kalacaktır.Tıklama işlemi yapıldığında bool nesnemiz true olacak ve faremizin oyun penceresi üzerinde tıklandığı koordinatı bir kenara ( Vector2 parametrelerinden birine ) kaydedeceğiz.Bool nesnemiz true iken tıklandığını göstermek amacıyla bir imaj dosyası çizdirilecektir.Farenin imlecinin çiziminde ise elimizde ki imleç imajını kullanacağız ve konum olarak ise XNA kütüphanesinden mouse ile ilgili sınıftan gelen nesnemizden faydalanacağız.Anlattığım şeyler belki karışık olabilir.Bütün bunları kodda 
anlamak daha rahat.

Texture2D mouseClickTexture; // Mouse a sol tıkladığında ekranda belirecek işaretleyici imaj dosyası için
        Texture2D mouseCursorTexture; //Mouse imleç imaj dosyası için
        Vector2 positionOfMouse; // Mouse için ekranda bulunduğu konumu tutacağımız değişken
        Vector2 lastClickPosition; //Ekranda mouse a tıklanan koordinat kaydı için
        bool isClicked; //Mouse a tıklanıp tıklanmadığını denetleyebileceğimiz değişken

Bütün bu alanları tanımladıktan sonra bunlara Game1 sınıfında gerekli yüklemeleri yapabildiğimiz LoadContent metotumuz içerisinde el atıyoruz.


protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            mouseClickTexture = Content.Load("mouseClick"); // mouseClick dosyası için tıklayınız...
            mouseCursorTexture = Content.Load("mouse_cursor"); // mouse_cursor dosyası için tıklayınız...
            isClicked = false; // Mouse a tıklanmadığı zamanlarda hep false olmasını istemekteyiz
        }


Gerekli kontrollerin veya güncellemelerin yapıldığı Update fonksiyonu içerisinde MouseController(2) diye bir metot kullanacağız.Bu metot içerisinde 
mouse a tıklanıp tıklanılmadığını kontrol edip yukarıda tanımladığımız positionOfMouse değişkenine devamlı olarak farenin konumunu atıyoruz.Bunu yapmamızın nedeni mouseCursorTexture ü fare imlecinin bulunduğu yerde çizdirilmesini sağlamak.Şimdi MouseController metotunu yazalım.
public void MouseController() 
        {
  // using Microsoft.Xna.Framework.Input alan adı ile gelen sınıflar ile mouse durumlarını aktarabileceğimiz 
  //myMouse değişkeni oluşturuluyor

            MouseState myMouse = Mouse.GetState(); 


   //Mouse a sol tık yapılıp yapılmadığını sorguluyoruz
            if (myMouse.LeftButton == ButtonState.Pressed)
            {
//Eğer sol tıklandıysa bu aşamaya geldik demektir.
//isClicked değişkenini true yapıyoruz ve ek olarak tıklanan konumu lastClickPosition değişkenine kaydediyoruz
//Bunu yapmamızda ki amaç önceden söylediğimiz gibi ekranda tıklanan konumu gösterme amaçlı imaj görüntülerken ihtiyacımızın olacağındandır
                
isClicked = true;
                lastClickPosition = new Vector2(myMouse.X,myMouse.Y);
            }

   //Sürekli olarak mouse un ekranda bulunduğu konumu positionOfMouse a kaydediyoruz

            positionOfMouse = new Vector2(myMouse.X, myMouse.Y);
}


MouseController metotunu Update içerisinde yazıyoruz.Son olarak yaptıklarımızı görüntüleme kısmına geliyoruz.

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            
            spriteBatch.Begin();

   //Fare imlecini çizdiriyoruz genişlik ve uzunluk olarak 16 ya 16 piksel olarak düşündüm.İsteğe bağlı olarak büyütüp küçültebilirsiniz.

            spriteBatch.Draw(mouseCursorTexture,new Rectangle((int)positionOfMouse.X,(int)positionOfMouse.Y,16,16),Color.White);

            //Eğer isClicked==true ise
            if (isClicked) 
            {
//Tıklanan yeri gösterecek imaj dosyası görüntülenir ve isClicked false yapılır.Bunun nedeni işaretleyicinin son tıklanan yeri göstermesi,
//eskilerinin diğer tıklama işlemine kadar ekranda kalmamasını sağlamak.
//Burada çizim işlemi belirtilirken konum kısmının fare imleci çizdirilirken kullandığımız konum bilgilerinden farklı olmasının sebebi 
                //XNA de 2D sprite çizim mantığıyla alakalı bir durumun varlığıdır.Önceki yazılardan hatırladığımız gibi çizilecek şeklin konumu en sol üst köşesini
//göstermekteydi.Buda işeretleme açısından uygun kaçmamaktadır.Tıkladığımız yerin işaretleme imajının tam ortasına denk gelmesini istedim.
//Dilerseniz new Vector2(positionOfMouse.X,positionOfMouse.Y)  olarak aşağıda bir deneme yapabilirsiniz.

                spriteBatch.Draw(mouseClickTexture,new Vector2(positionOfMouse.X-mouseClickTexture.Width/2,positionOfMouse.Y-mouseClickTexture.Height/2),Color.White);
                isClicked = false;
            }

            spriteBatch.End();
            
            base.Draw(gameTime);
        }

Şimdi projemizin son durumuna birlikte göz atalım.


Son olarak basit bir deneme daha yapıp yazımızı sonlandıralım istiyorum.Daha önceki yazılarda kullandığımız denizanası imajımızı ekranda tıkladığımız yere doğru hareket eden basit bir takipçi karakter haline getirmeye çalışalım.Bu aşamada arkaplan ve denizanası resimlerinin yüklemesi veya çizdirilmesi için gerekli ayarlamaları önceki yazılardan bildiğimizi varsayıyorum.Öyle olmasa bile en altta vereceğimiz kodlardan anlayabileceğiniz umuyorum.Takip için sadece Game1 sınıfı içerisinde Update metotuna birkaç satır kod ekleyeceğim.

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            MouseController() ;

            
   //Burada basit bir şekilde tıklanan noktaya doğru hareket eden bir denizanasının konumu üzerinde ki değişiklikleri görüyoruz

            if(lastClickPosition.X>position.X)
            {
                position.X += 2;
            }
            if (lastClickPosition.X < position.X )
            {
                position.X -= 2;
            }

            if (lastClickPosition.Y > position.Y )
            {
                position.Y += 2;
            }

            if (lastClickPosition.Y < position.Y )
            {
                position.Y -= 2;
            }

            base.Update(gameTime);
        }


Kaynak Kod: 
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace WindowsGame3
{
   public class Game1 : Microsoft.Xna.Framework.Game
   {
       GraphicsDeviceManager graphics;
       SpriteBatch spriteBatch;
       Vector2 position;
       Texture2D background;
       Texture2D texture;
       Texture2D mouseClickTexture;
       Texture2D mouseCursorTexture;
       Vector2 positionOfMouse;
       Vector2 lastClickPosition;
        bool isClicked;
        
       public Game1()
       {
           graphics = new GraphicsDeviceManager(this);
           Content.RootDirectory = "Content";
       }
       protected override void Initialize()
       {
           base.Initialize();
       }
       protected override void LoadContent()
       {
           spriteBatch = new SpriteBatch(GraphicsDevice);
           texture = Content.Load("denizanasi");
           background = Content.Load("arkaplan");
           mouseClickTexture = Content.Load("mouseClick");
           mouseCursorTexture = Content.Load("mouse_cursor");
            position = new Vector2(0,0);
           lastClickPosition = position;
           isClicked = false;
       }
       protected override void UnloadContent()
       {
          
       }
       protected override void Update(GameTime gameTime)
       {
           if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
               this.Exit();

           MouseController() ;
           
           if(lastClickPosition.X>position.X)
           {
               position.X += 2;
           }
           if (lastClickPosition.X < position.X )
           {
               position.X -= 2;
           }
           if (lastClickPosition.Y > position.Y )
           {
               position.Y += 2;
           }
           if (lastClickPosition.Y < position.Y )
           {
               position.Y -= 2;
           }
           base.Update(gameTime);
        }
       
       public void MouseController() 
       {
           MouseState myMouse = Mouse.GetState();
           if (myMouse.LeftButton == ButtonState.Pressed)
           {
               isClicked = true;
               lastClickPosition = new Vector2(myMouse.X,myMouse.Y);
           }
           positionOfMouse = new Vector2(myMouse.X, myMouse.Y);
       }
       protected override void Draw(GameTime gameTime)
       {
           GraphicsDevice.Clear(Color.CornflowerBlue);
           
           spriteBatch.Begin();
           spriteBatch.Draw(background, new Rectangle(0,0,graphics.PreferredBackBufferWidth,graphics.PreferredBackBufferHeight), Color.White);
           spriteBatch.Draw(texture,position,Color.White);
           spriteBatch.Draw(mouseCursorTexture,new Rectangle((int)positionOfMouse.X,(int)positionOfMouse.Y,16,16),Color.White);
           if (isClicked) 
           {
               spriteBatch.Draw(mouseClickTexture,new Vector2(positionOfMouse.X-mouseClickTexture.Width/2,positionOfMouse.Y-mouseClickTexture.Height/2),Color.White);
               isClicked = false;
           }
           spriteBatch.End();
           
           base.Draw(gameTime);
       }
   }
}


(1)XNA maalesef otomatik olarak bir mouse işaretçisi bizim için ekranda göstermiyor.Kendimiz gerekli konumu tespit edip elimizde ki herhangi bir imleç imajı ile bunu halledebilmeliyiz.Ya da bütün bu yazıda anlattığımız imleç gösterme yolunu bir kenara koyarak Game1 sınıfı içerisinde LoadContent metotu içerisinde this.IsMouseVisible = true;  satırını ekleyerek mouse cursor un görüntülenmesini sağlayabiliriz.

(2)Daha önce incelediğimiz Klavye işlemleri için KeyboardController isimli bir metot oluşturup bunu Update içerisinde çağırabilirsiniz
public void KeyboardController() 
       {
           KeyboardState keyboard = Keyboard.GetState();
           if (keyboard.IsKeyDown(Keys.Up))
           {
               this.position.Y -= 2;
           }
           if (keyboard.IsKeyDown(Keys.Down))
           {
               this.position.Y += 2;
           }
           if (keyboard.IsKeyDown(Keys.Right))
           {
               this.position.X += 2;
           }
           if (keyboard.IsKeyDown(Keys.Left))
           {
               this.position.X -= 2;
           }
       }

Comments(0):
Bu yazı için henüz bir yorum yapılmamış
Yorum yapabilmeniz için üye olmanız gerekmektedir,(Giriş Yap|| Üye Ol)