Windows Phone 7 – XNA ile Gesture Kullanımı

Standard

Windows Phone 7 için yazdığımız bir uygulamada, “gesture” dediğimiz el hareketlerini kullanarak dokunmatik ekranın özelliklerinden çok daha etkili faydalanabiliriz. Ekrana çift dokunma, basılı tutma ya da sürükleme tarzı hareketleri uygulamamıza etkili bir şekilde yerleştirmek ise XNA Framework içindeki pek çok hazır sınıf sayesinde düşündüğünüzden çok daha kolay. Bu yazımda, birlikte içinde gesture kullanacağımız bir XNA programı yazacağız.

Öncelikle, işe Visual Studio içinde yeni bir Windows Phone Game projesi açarak başlayalım. Bu projenin adını WP7GestureXNA koydum. Projeyi açarken versiyon sorduğunda da Windows Phone 7.1 seçelim.

Gesture kullanabilmemiz için öncelikle uygulamamızda kullanmak istediğimiz hareketleri aktifleştirmemiz gerekli. Tabi ki eğer istersek bütün hareketleri aktifleştirebiliriz, ancak bu uygulamamızın performansı üstüne gereksiz bir yük bindirecektir.

Daha da ilerlemeden önce, Windows Phone 7 içindeki gesture tiplerini inceleyelim:

Tap: Tıklama benzeri, parmağımızı hızlıca dokundurup kısa sürede geri çekme hareketidir.

Double Tap: Çift tıklama benzeri, ardı ardına yapılan iki Tap hareketidir.

Hold: Parmağımızı dokundurup hareket ettirmeden kısa bir süre bekleme hareketidir.

VerticalDrag: Dikey eksende, yani yukarı – aşağı yapılan sürükleme hareketidir.

HorizontalDrag: Yatay eksende, yani sağa – sola yapılan sürükleme hareketidir.

FreeDrag: Herhangi bir yönde yapılan serbest sürükleme hareketidir.

Flick: Parmağımızı hızlıca ekran boyunca sürükleyerek geri çekme hareketidir. Genelde ekranı ya da menüleri kaydırmak için yapılır.

Pinch: İki parmağımızı dokundurup hareket ettirerek yaptığımız harekettir. Genelde yakınlaşma – uzaklaşma ya da döndürme işlemleri için kullanılır.

Uygulamamız içinde hangi hareketleri kullanacağımıza karar verdikten sonra, aşağıdaki kod ile bunları aktifleştiriyoruz. Ben DoubleTap, Hold ve FreeDrag hareketlerini seçtim.

        protected override void Initialize()
        {
            TouchPanel.EnabledGestures = GestureType.DoubleTap | GestureType.Hold | GestureType.FreeDrag;

            base.Initialize();
        }

Uygulamamız şu şekilde olsun: Ekranda DoubleTap yaptığımızda mavi, Hold yaptığımızda yeşil, ve FreeDrag yaptığımızda da kırmızı nokta o hareketi yaptığımız yere çizilsin. Bunu sağlamak için, öncelikle boş (yani tamamen beyaz) bir png dosyasını projemizin Content kısmına yükleyelim, projemize BlankTexture adında bir Texture2D objesi tanımlayalım ve LoadContent metodumuz içinde png dosyamızı yükleyelim.

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

            BlankTexture = Content.Load<Texture2D>("blank");
        }

Sırada hareket bilgilerini okumak var. Öncelikle dikkat etmemiz gereken ufak bir ayrıntıya bakalım. Bir el hareketi yapıldığının farkına varıldığında, bu hareket ile ilgili bilgiler TouchPanel sınıfında bir listeye atılır. Bu nedenle, her Update metodumuzda o anki bütün yapılmış hareketlerin bilgilerini kontrol etmemiz gereklidir. Eğer Update metodumuzda sadece tek bir hareket bilgisi alırsak, bu bazı hareket bilgilerini geç kontrol etmemiz ve aynı anda olmuş hareketleri kaçırmamız anlamına gelir. Update metodumuzu aşağıdaki şekilde bir while döngüsü içerisinde yazarsak o anki tüm hareketleri kontrol ederek böyle bir sorunla karşılaşmayız:

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

            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gesture = TouchPanel.ReadGesture();

                switch (gesture.GestureType)
                {
                    //TODO: Bir şeyler yap
                }
            }

            base.Update(gameTime);
        }

Şu anda hareketlerimizi de algılayabiliyoruz. Geriye sadece bu hareketleri ekrana çizmek kaldı. Bunun için ilk olarak her hareket için bir X ve Y olmak üzere 6 adet float tanımlıyoruz, bu değerlere başlangıçta 0 vererek initialize ediyoruz, ve Update metodumuz içindeki döngüyü aşağıdaki gibi dolduruyoruz:

            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gesture = TouchPanel.ReadGesture();

                switch (gesture.GestureType)
                {
                    case GestureType.DoubleTap:
                        {
                            DoubleTapX = gesture.Position.X;
                            DoubleTapY = gesture.Position.Y;
                            break;
                        }
                    case GestureType.Hold:
                        {
                            HoldX = gesture.Position.X;
                            HoldY = gesture.Position.Y;
                            break;
                        }
                    case GestureType.FreeDrag:
                        {
                            FreeDragX = gesture.Position.X;
                            FreeDragY = gesture.Position.Y;
                            break;
                        }
                }
            }

Hareket ile ilgili bilgileri almak için kullandığımız GestureSample sınıfında GestureType dışında 5 tane bilgi bulunmaktadır: Timestamp, Position, Delta, Position2 ve Delta2. Position, adından da anlaşılacağı gibi hareketin gerçekleştiği noktayı veren bir 2 boyutlu vektördür. Delta ise hareketin yer değiştirmesini bize verir. Position2 ve Delta2, iki parmağın kullanıldığı Pinch hareketinde ikinci parmağın bilgilerini tutar. Timestamp ise bize hareketin gerçekleştiği zaman ile ilgili bilgi veren bir TimeSpan objesidir. Ancak Timestamp objesinin oyunumuzdaki GameTime ile ilgisi yoktur, sadece iki ayrı hareketin birbirleri ile olan ilişkisini belirlememiz için kullanılır. Örneğin iki ayrı hareketin Timestamp değerlerini birbirinden çıkararak aralarında kaç saniye fark olduğunu bulabiliriz.

Artık çizim yapmak için koordinatlarımız da olduğuna göre, Draw metodumuzu aşağıdaki gibi doldurarak ekrana çizim yapabiliriz:

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

            spriteBatch.Begin();

            spriteBatch.Draw(BlankTexture, new Rectangle((int)DoubleTapX, (int)DoubleTapY, 10, 10), Color.Blue);
            spriteBatch.Draw(BlankTexture, new Rectangle((int)HoldX, (int)HoldY, 10, 10), Color.Green);
            spriteBatch.Draw(BlankTexture, new Rectangle((int)FreeDragX, (int)FreeDragY, 10, 10), Color.Red);

            spriteBatch.End();

            base.Draw(gameTime);
        }

Bütün bunları yaptığımız zaman, sonuç olarak karşımıza böyle bir uygulama çıkacak:

Telefon ekranında çift tıkladığımız yerde mavi, basılı tuttuğumuz yerde yeşil ve tutup sürüklediğimiz yerde kırmızı bir kare var. 🙂

Bu el hareketlerini kullanarak pek çok şey yapmamız mümkün, FreeDrag hareketi ile oyunumuz içinde bir şeyler tutup fırlatabilir, VerticalDrag ve HorizontalDrag ile kayan menüler yapabilir, Pinch ile bir şeyleri büyütüp küçültebilir ya da ekranı döndürebilir, veya Hold ile bir şeye basılı tuttuğumuzda menü açılmasını sağlayabiliriz. Yani gerisi hayal gücümüze kalmış. 🙂

Bu projenin kaynak koduna buradan erişebilirsiniz.

Gelecek yazılarımda görüşmek üzere. 🙂

Advertisements

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s