Ağustos 2011 - Microsoft Yaz Okulu Ankara Semineri

Her sene üniversitelerin yaz tatiline girmesiyle Microsoft tarafından bir Yaz Okulu oluşturuluyor.

Bu yıl ben de Microsoft Yaz Okuluna eğitmen olarak katıldım.

İlk seminerimi Ankara TOBB Ekonomi ve Teknoloji Üniversitesi‘nde XNA Oyun Programlama konusunda verdim.

Ankara Yaz Okulu öğrencilerine, beni sabırla dinledikleri için teşekkür ediyor, özverili katılımlarından dolayı da tebrik ediyorum.

XNA Oyun Programlama Sunum Dosyası‘nı download edebilirsiniz.

Ağustos 2011 Etkinliklerim

Ağustos ayı içerisinde planlanan seminerlerim;

01 Ağustos 2011 - Microsoft Yaz Okulu (Ankara) - XNA Oyun Programlama

07 Ağustos 2011 - BilgeAdam Eğitim Akademisi (İzmir) - XNA Oyun Programlama

08 Ağustos 2011 - Microsoft Yaz Okulu (İzmir) - XNA Oyun Programlama

15 Ağustos 2011 - Microsoft Yaz Okulu (İstanbul) - XNA Oyun Programlama

XNA oyunlarında saniyedeki kare sayısını (FPS) hesaplamak

Hemen her oyun’da, saniyede çizilen ekran sayısı (FPS - Frame Per Second) bilgisi oyun penceresinde gösterilir.

FPS nedir?

FPS, oyunun bir saniye içerisinde oyun penceresine çizebildiği ekran sayısıdır. Bizim animasyon olarak gördüğümüz akışlar aslında ardı ardına hızlı bir şekilde çizilen tek kare resimlerdir.

Sinema filmleri bile aslında ekranda sırayla gösterilen tek kare resimlerden oluşmaktadır.

İnsan gözü, saniye 25 kare’den büyük hızlarda tek kare resimleri, bir akış olarak algılar.

XNA Framework, saniyede 60 kare ekran çizmeye çalışır.

Oyunlarımızda FPS nasıl hesaplarız?

Formül aslında basit, Draw() method’unda bir değişkenin değerini 1 arttıracağız. Update() method’unda her saniye geçişinde değişkeni sıfırlayacağız.

FPS bilgisini ekranda nasıl gösteririz?

Draw() method’unda değişkenin değerini ekranda gösterirsek, bir saniye içerisinde kaç defa Update() method’unun çalıştırıldığını, yani saniyedeki ekran sayısını (FPS) göstermiş oluruz.

Şimdi yazacağımız örnek projede, klavyeden boşluk (space) tuşuna basıldığında FPS bilgisini ekranda göstereceğiz, tekrar basıldığında gizleyeceğiz.

Örnek proje

Öncelikle sınıf seviyesinde değişkenlerimizi oluşturalım;

int SaniyedeKareSayisi = 0; double FPS = 0; bool DetayGoster = false; KeyboardState pks;</pre>

Update() method’unda FPS hesaplayalım;

KeyboardState ks = Keyboard.GetState();

if (pks.IsKeyDown(Keys.Space) && ks.IsKeyUp(Keys.Space))
{
    DetayGoster = !DetayGoster;
}

if (DetayGoster && gameTime.TotalGameTime.Milliseconds == 0)
{
    FPS = SaniyedeKareSayisi;
    SaniyedeKareSayisi = 0;
}

pks = ks;

Oyun penceresinde yazı gösterebilmek için, SpriteFont sınıfından bir değişkene ihtiyacımız olacak.

SpriteFont Arial;

Content projemize Arial isminde bir SpriteFont dosyası ekleyelim.

XNA Oyun Programlama - FPS Hesaplama / SpriteFont Ekleme Dialog Kutusu

<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">
    <FontName>Arial</FontName>
    <Size>24</Size>
    <Spacing>0</Spacing>
    <UseKerning>true</UseKerning>
    <Style>Regular</Style>
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#126;</End>
      </CharacterRegion>
    </CharacterRegions>
  </Asset>
</XnaContent>

LoadContent() method’unda Arial değişkenimize değer atayalım;

Arial = Content.Load("Arial");

Draw() method’unda hesaplanan FPS bilgisini ekranda gösterelim;

spriteBatch.Begin();

if (DetayGoster)
{
    SaniyedeKareSayisi++;

    spriteBatch.DrawString(Arial, "FPS : " + FPS.ToString(), new Vector2(50, 50), Color.Black);
}

spriteBatch.End();


Artık oyun penceremizde *saniyedeki ekran sayısını* (**FPS**) gösterebiliriz.

![XNA Oyun Programlama - FPS Hesaplama Sonucu](/assets/uploads/2011/07/FPSGameScreen.png "XNA Oyun Programlama - FPS Hesaplama Sonucu")

Oyunun kodlarını indirmek için tıklayınız.

C# ile Geçici Dosya (Temporary File) oluşturma sınıfı yazalım

Projelerimizde dosya sistemi üzerinde geçici olarak dosya oluşturma ve işimiz bittiğinde silme ihtiyacı hissedebiliriz.

Bu yazıyı okumadan önce Hem benzersiz hem de geçici dosya oluşturmanın en kolay yolu ve C# ile Geçici Dosya Oluşturmak başlıklı yazılarımı okumanızı öneririm.

Bu linkte bulduğum yöntemi çok kullanışlı buldum ve sizler (aynı zamanda kendim) için türkçeleştirdim;

public class TempFile : IDisposable { public TempFile() : this(string.Empty) { }

private readonly string _tmpfile;

public TempFile(string extension)
{
    _tmpfile = Path.GetTempFileName();

    if (!string.IsNullOrEmpty(extension))
    {
        string newTmpFile = _tmpfile + extension;

        /// Yeni bir geçici dosya oluşturulur
        File.Create(newTmpFile, 0);
        /// Eski geçici dosya silinmediyse, silinir.
        File.Delete(_tmpfile);

        /// Yeni oluşturulan geçici dosya kullanıma hazır!
        _tmpfile = newTmpFile;
    }
}

public string FullPath
{
    get { return _tmpfile; }
}

void IDisposable.Dispose()
{
    if (!string.IsNullOrEmpty(_tmpfile) && File.Exists(_tmpfile))
    {
        File.Delete(_tmpfile);
    }
} }</pre>

Kullanımına örnek;

using(TempFile tmp = new TempFile(".dat")) /// dat uzantılı bir geçici dosya oluşturuluyor
{
    /// FullPath özelliğinden geçici dosyanın yolu ve dosya adı alınabilir;
    string filename = tmp.FullPath;
}


XNA ile Karakter Hareketi

Bu yazımı okumadan önce XNA ile Oyun Programlama konulu diğer yazılarımı okumanızı tavsiye ederim.

Her oyunda bir ana karakter vardır ve biz oyuncular olarak, bu ana karakteri mouse/klavye/joystik aracılığıyla oyun evreninde kontrol ederiz.

Bu yazımda önce bir oyun evreni oluşturacak, sonra da ana oyun karakterini bu evrende hareket ettireceğiz.

Önce oyunda kullanacağımız görselleri bilgisayarımıza indirelim;

XNA ile Oyun Programlama - Karakter Hareket Çim ArkaPlan XNA ile Oyun Programlama - Karakter Hareket Sprite

Öncelikle arkaplan ve ana karakterimiz için sınıf seviyesinde değişkenlerimizi oluşturalım;

Texture2D KarakterSprite; Texture2D ArkaplanCim;</pre>

Klavye bilgisini alabilmek için KeyboardState sınıfından bir değişken ekleyelim;

KeyboardState ks;

Vector2 sınıfından bir değişken ile, ana karakterimizin oyun penceresinde konumunu tutalım;

Vector2 KarakterKonum;

Oyun sınıfının constructor‘ında (Game1 ismini GameLoop olarak değiştirelim) KarakterKonum değişkenine başlangıç değerini verelim;

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

    KarakterKonum = new Vector2(50, 50);
}

LoadContent() method’unda ArkaplanCim ve KarakterSprite değişkenlerine değer atayalım;

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

    KarakterSprite = Content.Load<Texture2D>("KarakterSprite");
    ArkaplanCim = Content.Load<Texture2D>("Cim");
}

KarakterSprite görselinde, karakterimizin dört yöne yapacağı hareketlerin tek tek görüntüleri yer alıyor.

Karakterimize yürüme efekti vermek için, aslında birden fazla görselden oluşan tek bir görsel kullanıyoruz. (Böylece hafızaya tek bir görsel yüklendiği için hafıza kullanımını az tutmuş oluyoruz)

Sırayla görselin herbir parçasını ekranda karakterimiz olarak çizdiğimizde, karaktere yürüme efektini vermiş oluyoruz.

Bir Sprite‘ın bir parçasını ekrana çizdirmek için, SpriteBatch sınıfının Draw() method’undan faydalanırız;

SpriteBatch.Draw(Texture2D, Vector2, Rectangle, Color);

Bu method’un parametreleri;

  • Texture2D, ekrana çizdireceğimiz görselin bulunduğu görseli yüklediğimiz değişken
  • Vector2, görselin ekranda çizileceği konum
  • Rectangle, görselin ekrana çizilecek parçası (Left-Top-Width-Height isminde dört özelliği vardır)
  • Color, görsele uygulanacak baskın renk değişkeni

Sınıf seviyesine aşağıdaki değişkenleri ekleyerek devam edelim;

Rectangle Arkaplan;
Rectangle Karakter;

int Kare = 0;

int Yon = 0;

GameLoop sınıfının constructor‘ına;

Arkaplan = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);

ekleyelim. Böylece, arkaplan görselinin çizileceği alanı tanımlamış olduk.

Oyun kodlarımızın en önemli iki methodundan biri, Update() method’udur;

ks = Keyboard.GetState();

if (ks.IsKeyDown(Keys.Escape))
{
    this.Exit();
}

if (ks.IsKeyDown(Keys.Down))
{
    Yon = 0;
    Kare++;
    KarakterKonum.Y += 3;
}
else if (ks.IsKeyDown(Keys.Up))
{
    Yon = 1;
    Kare++;
    KarakterKonum.Y -= 3;
}
else if (ks.IsKeyDown(Keys.Left))
{
    Yon = 2;
    Kare++;
    KarakterKonum.X -= 3;
}
else if (ks.IsKeyDown(Keys.Right))
{
    Yon = 3;
    Kare++;
    KarakterKonum.X += 3;
}

if (Kare > 5)
{
    Kare = 0;
}

Her bir yön tuşuna basıldığında Yon değişkenini farklı bir değere atadık. Ayrıca Kare değişkeninin değerini de bir artırdık.

KarakterSprite görselinde karakter’in yürüme efekti için yana doğru 6 görsel kullanıldığını görüyoruz. Kare değişkeni 5 değerinden büyük bir değere ulaştığında 0 değerine eşitleyip değişkeni sıfırlamış oluyoruz.

Her yön tuşuna basıldığında Yon değişkenine verdiğimiz değer, KarakterSprite görselinde ilgili tuşa ait yönün yukarıdan aşağıya sıra numarası aynı zamanda.

Son adımda, Draw() method’unu yazıyoruz;

GraphicsDevice.Clear(Color.CornflowerBlue);

Karakter = new Rectangle(Kare * 24, Yon * 32, 24, 32);

spriteBatch.Begin();

spriteBatch.Draw(ArkaplanCim, Arkaplan, Color.White);
spriteBatch.Draw(KarakterSprite, KarakterKonum, Karakter, Color.White);

spriteBatch.End();


Öncelikle Rectangle tipinde *Karakter* değişkenine, *KarakterSprite* değişkeninin hangi **parçasını** ekrana çizmek istediğimizi belirteceğimiz değeri atıyoruz.

Sonra *arkaplan* ve *karakterimizi* oyun penceresine **çizdiriyoruz**.

![XNA ile Oyun Programlama - Karakter Hareket Oyun Ekranı](/assets/uploads/2011/07/XNAKarakterHareket.png "XNA ile Oyun Programlama - Karakter Hareket Oyun Ekranı")

Oyunun kodlarını indirmek için tıklayınız.

Engin Polat hakkında

Chief Architect, Microsoft RD, Microsoft MVP

Ada ve Ege'nin babası ;)

Kategoriler

İstatistik

Makale Adedi: 458

Creative Commons Lisansı