Windows Phone 8 - XNA Oyunu / Savaşa Hayır

Bu yazımı okumadan önce Windows Phone ve XNA konusundaki diğer makalelerimi okumanızı öneririm.

Önce görseller;

Savaşa Hayır : BackgroundSavaşa Hayır : Drop 1 0Savaşa Hayır : Drop 1 1Savaşa Hayır : Drop 2 0Savaşa Hayır : Drop 2 1Savaşa Hayır : Plane 0Savaşa Hayır : Plane 1Savaşa Hayır : Plane 2Savaşa Hayır : Plane 3Savaşa Hayır : Plane 4Savaşa Hayır : Plane 5

İlk olarak XNA Game Studio 4.0 grubundaki Windows Phone Game şablonundan SavasaHayir isimli projeyi oluşturalım;

Windows Phone : XNA Game Project Template

Game1.cs dosyasının ismini GameLoop.cs olarak değiştirdikten sonra, Plane isminde yeni bir class ekleyelim;

public class Plane { public Texture2D Texture;

public int Location;

public int Speed; }</pre>

Plane sınıfı sayesinde, ekrana getireceğimiz uçakların telefon ekranındaki konumlarını, hızlarını ve görsellerini bileceğiz.

Drop isminde yeni bir class daha ekleyelim ve aşağıdaki kod parçası ile güncelleyelim;

public class Drop
{
    public bool IsBox;

    public bool IsParachute;

    public Vector2 Location;
}

GameLoop sınıfına geri dönelim ve sınıf seviyesindeki değişkenlere aşağıdakileri ekleyelim;

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

Random r = new Random();

Texture2D BackgroundTexture;

Texture2D BoxTexture;
Texture2D BoxParachuteTexture;

Texture2D HumanTexture;
Texture2D HumanParachuteTexture;

Texture2D[] PlaneTextures = new Texture2D[6];

List<Plane> PlaneList = new List<Plane>();

List<Drop> DropList = new List<Drop>();

TimeSpan LastPlaneDate = TimeSpan.Zero;

int PlaneCount;
int DropCount;
int HelpCount;

Yukarıdaki kodlar için daha önce yazmış olduğum Windows Phone ve XNA konusundaki diğer makalelerimi okumanızı öneririm.

GameLoop sınıfının constructor‘ında aşağıdaki atama işlerini yapalım;

public GameLoop()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    TargetElapsedTime = TimeSpan.FromTicks(333333);

    InactiveSleepTime = TimeSpan.FromSeconds(1);

    graphics.PreferredBackBufferWidth = 480;
    graphics.PreferredBackBufferHeight = 800;

    graphics.IsFullScreen = true;
}

LoadContent method’unda Texture2D tipindeki değişkenlerimize değer atayalım;

spriteBatch = new SpriteBatch(GraphicsDevice);

BackgroundTexture = Content.Load<Texture2D>("Background");

for (int iLoop = 0; iLoop < 6; iLoop++)
{
    PlaneTextures[iLoop] = Content.Load<Texture2D>("Plane" + iLoop);
}

BoxTexture = Content.Load<Texture2D>("Drop1_0");
BoxParachuteTexture = Content.Load<Texture2D>("Drop1_1");

HumanTexture = Content.Load<Texture2D>("Drop2_0");
HumanParachuteTexture = Content.Load<Texture2D>("Drop2_1");

Update method’unda Plane ve Drop listesindeki elemanların yerlerini güncelliyoruz;

</pre><pre class="brush:csharp">foreach (var plane in PlaneList) { plane.Location += plane.Speed; }

foreach (var drop in DropList) { drop.Location.Y += 4; }</pre>

Son uçak üretme zamanımızdan itibaren 5000ms (5sn) geçtiyse yeni uçak üretme kodunu ekliyoruz;

LastPlaneDate += gameTime.ElapsedGameTime;

if (LastPlaneDate > TimeSpan.FromMilliseconds(5000))
{
    var plane = new Plane();

    plane.Texture = PlaneTextures[r.Next(0, 6)];

    plane.Speed = r.Next(3, 8);

    PlaneList.Add(plane);

    PlaneCount++;

    LastPlaneDate = TimeSpan.Zero;
}

Windows Phone oyunlarında, oyuncunun ekrana dokunduğu noktaların listesini TouchPanel sınıfının static GetState methodundan dönen TouchCollection ile alabilmekteyiz.

TouchCollection koleksiyonunun her bir elemanı TouchLocation tipindedir, State özelliğinin TouchLocationState enum’ından Pressed değerinde olduğunu kontrol ederek, ilgili noktaya dokunulduğu durumu yakalayabiliriz.

Eğer dokunulan nokta bir Plane ile kesişiyorsa, rastgele yeni bir Drop düşürebiliriz, Drop ile kesişiyorsa paraşütünün açılmasını sağlayabiliriz;

foreach (var tl in TouchPanel.GetState())
{
    if (tl.State == TouchLocationState.Pressed)
    {
        var touchArea = new Rectangle((int)tl.Position.X, (int)tl.Position.Y, 1, 1);

        foreach (var plane in PlaneList)
        {
            var planeArea = new Rectangle(plane.Location, 20, plane.Texture.Width, plane.Texture.Height);

            if (planeArea.Intersects(touchArea))
            {
                var drop = new Drop();

                drop.Location = new Vector2(tl.Position.X, 20);

                drop.IsBox = (r.Next(0, 2) == 0);

                DropList.Add(drop);

                DropCount++;

                return;
            }
        }

        foreach (var drop in DropList)
        {
            var dropArea = new Rectangle((int)drop.Location.X, (int)drop.Location.Y, 100, 200);

            if (!drop.IsParachute && dropArea.Intersects(touchArea))
            {
                drop.IsParachute = true;

                HelpCount++;

                return;
            }
        }
    }
}

Son olarak Draw method’unda elimizdeki arkaplan görselini, ekrandaki uçakları, paraşütü açılmış ve açılmamış nesneleri ekrana çizdireceğiz;

GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();

spriteBatch.Draw(BackgroundTexture, Vector2.Zero, Color.White);

foreach (var plane in PlaneList)
{
    spriteBatch.Draw(plane.Texture, new Vector2(plane.Location, 20), Color.White);
}

foreach (var drop in DropList)
{
    if (drop.IsBox && drop.IsParachute)
    {
        spriteBatch.Draw(BoxParachuteTexture, drop.Location, Color.White);
    }
    else if (drop.IsBox && !drop.IsParachute)
    {
        spriteBatch.Draw(BoxTexture, drop.Location, Color.White);
    }
    else if (!drop.IsBox && drop.IsParachute)
    {
        spriteBatch.Draw(HumanParachuteTexture, drop.Location, Color.White);
    }
    else
    {
        spriteBatch.Draw(HumanTexture, drop.Location, Color.White);
    }
}

spriteBatch.End();


Oyun'dan bir ekran görüntüsü;

![Savaşa Hayır : Screenshot](/assets/uploads/2014/01/SavasaHayir-2.jpg)

Windows Phone 8 uygulaması için Splash Screen hazırlamak

Eğer Windows Phone 7 için uygulama geliştirdiyseniz zaten Splash Screen sayfalarına aşinasınızdır. Genellikle uygulamanın logosunu içeren jpg formatında olan resim, uygulama açılırken ekrana gelir ve tamamen hafızaya yüklendiğinde otomatik olarak kaldırılırdı.

Performans’ta yapılan çok ciddi iyileştirmeler sayesinde Windows Phone 8 uygulamalarının Splash Screen ihtiyacı ortadan kalktı ve Windows Phone 7 proje şablonlarının bir parçası olan Splash Screen, Windows Phone 8 proje şablonlarından kaldırıldı.

Eğer projenizde Splash Screen ihtiyacınız varsa, Assets klasörüne SplashScreenImage.jpg isimli, 768 x 1280 boyutlarında bir resim eklemeniz yeterli.

Fakat uygulamanızın tüm ekran çözünürlüklerinde Splash Screen resmini doğru göstermesini istiyorsanız, 3 farklı boyutlarda resim daha eklemeniz gerekli.

  • 480 × 800 ekran çözünürlüğü için; SplashScreenImage.screen-WVGA.jpg
  • 768 × 1280 ekran çözünürlüğü için; SplashScreenImage.screen-WXGA.jpg
  • 720 × 1280 ekran çözünürlüğü için; SplashScreenImage.screen-720p.jpg

Eğer uygulamanız 1080p çözünürlükte bir cihazda açılıyorsa, 720p resmi kullanılacaktır.

Turkcell Teknoloji Zirvesi 2013 Etkinliği

Her yıl Turkcell tarafından organize edilen Turkcell Teknoloji Zirvesi‘ne bu yıl ben de konuşmacı olarak katıldım. 13 Kasım 2013 tarihinde Geleceği Yazanlar kategorisindeki Windows Phone 8 konulu oturumumu Haliç Kongre ve Kültür Merkezinde Cibali salonunda gerçekleştirdim.

Beni etkinliğe davet eden Turkcell‘deki komiteye ve etkinliğe katılan tüm katılımcılara teşekkür ederim.

C# ile uzun süren method'ları kontrol altına alın

Uygulama geliştirirken karşılaştığımız birçok senaryoda çağırdığımız bir method’un uzun sürede cevap üretmemesinden dolayı kaynaklarımızı tükettiğini görebiliriz.

Çağırılan method’un belli bir zaman aşımı süresine sahip olması ve bu süre sonuna kadar değer üretmediyse sonlanması için birçok yöntem kullanabiliriz, fakat ben System.Threading namespace‘inde yeralan CancellationTokenSource sınıfını kullanan aşağıdaki yöntemi tercih ediyorum;

/// <summary> /// Timeout süresinde tamamlanmayan method’u otomatik sonlandırır /// </summary> /// <param name=”action”>Çağırılacak method</param> /// <param name=”timeout”>Milisaniye cinsinden zamanaşımı süresi</param> /// <returns></returns> public static bool Execute(Action action, int timeout) { var tokenSource = new CancellationTokenSource();

var token = tokenSource.Token;

var task = Task.Factory.StartNew(action, token);

if (!task.Wait(timeout, token))
{
    tokenSource.Cancel();

    return false;
}

task.Dispose();

return true; }

/// <summary> /// Timeout süresinde tamamlanmayan method’u otomatik sonlandırır /// </summary> /// <param name=”action”>Çağırılacak method</param> /// <param name=”timeout”>Milisaniye cinsinden zamanaşımı süresi</param> /// <returns></returns> public static Tuple<bool, T> Execute<T>(Func<T> action, int timeout) { var result = Tuple.Create(false, default(T));

var tokenSource = new CancellationTokenSource();

var token = tokenSource.Token;

var task = Task.Factory.StartNew(() =&gt; { result = Tuple.Create(true, action.Invoke()); }, token);

if (!task.Wait(timeout, token))
{
    tokenSource.Cancel();
}

task.Dispose();

return result; }</pre>

Böylece değer döndürmeyen method’lar eğer timeout‘a uğramışsa geriye bool tipinde false değeri, timeout‘a uğramamışsa true değeri döndürebiliyoruz.

Geriye değer döndürecek method’lar eğer timeout‘a uğramışsa geriye Tuple sınıfından yeni bir değer döndürüyoruz. İki property’li Tuple‘ın birinci property’si timeout olup/olmadığını belirten bool tipinde, ikinci property ise çağırılan method’dan dönecek cevabın tipinin varsayılan değeri.

Bu methodlar sayesinde hatalar veya uzun süren method’ların kaynaklarımızı tüketmesi sorunları ile uğraşmadan uygulamalarımızı geliştirebiliriz.

Örnek kullanımlar;

Geriye değer döndürmeyen method’ları aşağıdaki örnek kullanım ile çağırabiliriz

var result = Execute(LongRunningProcess, 3000);

Geriye değer döndüren method’ları (örneğin int) aşağıdaki örnek kullanım ile çağırabiliriz

var result = Execute<int>(LongRunningProcess, 5000);


ASP.NET MVC Nedir, Ne İşe Yarar?

ASP.NET MVC, MVC pattern‘ini ASP.NET‘e eklemek için Microsoft‘un geliştirdiği framework’tür. ASP.NET MVC‘nin ne olduğunu anlamak için öncelikle MVC‘nin ne olduğunu incelemekte fayda var.

MVC, uygulama geliştirmede (özellikle web uygulaması geliştirmede) önemli yere sahip mimari desenlerden biridir. Günümüzde MVC denince akla Microsoft‘un geliştirdiği ASP.NET MVC Framework gelmektedir, oysa 1979 yılından beri (Microsoft 1975 yılında kurulmuştur) yazılım dünyasında yer almaktadır.

MVC, Model, View, Controller kelimelerinin baş harflerinden oluşur ve her kelime MVC‘nin farklı bir katmanını ifade eder.

Model MVC dünyasında model uygulama verisinin veya durumunun saklandığı yerdir, genellikle veritabanı veya xml/json dosyası formatındadır.

Model, veri katmanını (database, xml, json dosyası, vb.) uygulamadan izole eder, böylece diğer katmanlarda veri katmanının neresi olduğunun bilinmesine gerek kalmaz.

Model katmanı sıklıkla Entity Framework, Nhibernate, LLBLGen, vb. gibi araçlar kullanılarak oluşturulur.

View View, istemcinin gördüğü arayüzü içeren katmandır, genellikle Model katmanındaki verinin kullanılması ile oluşturulur. View katmanının Model ve Controller katmanlarından ayrılması ile arayüz değişikliklerinin uygulamanın diğer katmanlarını değiştirmeye gerek kalmadan yapılabilmesi sağlanmıştır.

View katmanında HTML5 ve CSS3 gibi son versiyon teknolojiler kullanmak mümkündür. HTML5 ve CSS3 ile masaüstü ve mobil tarayıcılarda çalışabilen uygulamalar geliştirmek çok kolaylaşmıştır.

Controller Controller, istemciden gelen isteği işlemek, Model ve View katmanları arasında köprü olmak gibi görevleri yerine getirir. Controller içerisinde bir veya daha fazla Action olabilir, genellikle her Action bir web sayfası üretmek için kullanılır.

MVC’nin diğer bir önemli yapıtaşı Routing mekanizmasıdır.

Routing Routing, istemci’nin uygulamaya yaptığı isteği uygun Controller ve Action‘a yönlendiren yapıdır. İstemci, isteği uygulamanın belli bir adresine gönderir, routing mekanizması sayesinde ilgili adres için en uygun Controller ve içerisindeki Action tespit edilir ve çalıştırılır.

Neden ASP.NET MVC tercih etmeliyim? MVC ile istemci’nin isteğine karşılık üretilen çıktı üzerinde çok büyük kontrol imkanı vardır. Bu sayede her alanına müdahele edebildiğimiz ve isteğe en uygun çıktının üretilebilmesi sağlanmıştır.

MVC ile tekrar kullanılabilir (reusable) kod üretmek mümkündür. MVC’nin katmanları birbirinden ayrıldığı için her bir katmanın başka projelerde kullanılabilmesi sağlanmıştır.

MVC ile istemci’nin istek göndereceği adresler üzerinde çok büyük kontrol imkanı vardır. Bu sayede adres’in içerik ile tam bir ilişki içerisinde olması sağlanmıştır. Arama motorları için adres-içerik ilişkisi önemli olduğu için uygulamanın bulunabilirliğine katkısı yüksektir.

MVC ile test edilebilir uygulamalar geliştirme çok kolaylaşmıştır. Katmanların birbirinden ayrı olması ve Test Driven Development yapmayı kolaylaştırıcı mimarisi sayesinde test edilebilir uygulama geliştirilebilmesi sağlanmıştır.

Sonuç MVC uzun yıllardır bir çok framework’te ve programlama dilinde kullanılmış (Java, PHP, vb.) ve olgunlaşmış bir desendir. ASP.NET MVC sayesinde .Net framework dilleri ile MVC pattern kullanılarak hızlı çalışan, test edilebilir, tekrar kullanılabilir parçaları olabilen web uygulamaları geliştirilebilmesi sağlanmıştır.

Engin Polat hakkında

Chief Architect, Microsoft RD, Microsoft MVP

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 459

Creative Commons Lisansı