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)

blog comments powered by Disqus

Engin Polat hakkında

Senior Software Engineer, @Microsoft

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 484

Creative Commons Lisansı