Arşiv

Etiketlenen yazılar getstate

XNA ile Karakter Hareketi

11 Temmuz 2011 2 yorum

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;

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ı

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

XNA Oyunu / Çanakkale Geçilmez – 1

11 Mayıs 2011 Yorum yapılmamış

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

Bu sefer yapacağımız oyun, 30 Ağustos‘un ruhuna uygun olacak – Çanakkale Geçilmez.

Önce görsellerimizi verelim;

XNA - Çanakkale Geçilmez - Arkaplan XNA - Çanakkale Geçilmez - Düşman Gemisi XNA - Çanakkale Geçilmez - Top XNA - Çanakkale Geçilmez - Gülle XNA - Çanakkale Geçilmez - Karakterler XNA - Çanakkale Geçilmez - Sayılar

İki tane de ses dosyamız var;

Gemi Vuruldu Sesi

Arkaplan Müziği

Başlayalım oyunumuzu yazmaya; Çanakkale Geçilmez projemizi oluşturduktan ve Game1.cs‘in ismini GameLoop.cs olarak değiştirdikten sonra, class seviyesindeki değişkenlerimizi tanımlayalım;

public const int PENCERE_GENISLIK = 800;
public const int PENCERE_YUKSEKLIK = 600;
public const bool TAM_EKRAN = false;

Texture2D Arkaplan;

Oyun penceremizin sınırlarını tutacağımız Rectangle tipinde bir değişkeni class seviyesindeki değişkenlerimize ekleyelim;

Rectangle Pencere;

Gelelim bu değişkenleri kullanmaya, GameLoop class‘ımızın constructor methodunda aşağıdaki kodları yazalım;

graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;
graphics.IsFullScreen = TAM_EKRAN;
Pencere = new Rectangle(0, 0, PENCERE_GENISLIK, PENCERE_YUKSEKLIK);

Ses dosyalarımız için class seviyesinde değişkenlerimiz tanımlayalım;

SoundEffectInstance ArkaplanSes;
SoundEffectInstance GemiVurulduSes;

LoadContent() method‘unda değişkenlerimize yükleme işlemlerini gerçekleştirelim;

Arkaplan = Content.Load<Texture2D>("Arkaplan");

ArkaplanSes = Content.Load<SoundEffect>("pong").CreateInstance();
GemiVurulduSes = Content.Load<SoundEffect>("ir_begin").CreateInstance();

ArkaplanSes.IsLooped = true;
ArkaplanSes.Volume = 0.3f;
ArkaplanSes.Play();

Ses dosyaları ile yaptığımız bu işlemleri XNA ile Pong oyunu yazalım – 2 yazımdan hatırlayacaksınız.

Bu oyunumuzda aktörleri Nesne Yönelimli Programlama (Object Orriented Programming) kurallarına uyarak oluşturalım; oyun projemize yeni bir class ekleyelim ve ismini GameObject.cs verelim.

Çanakkale Geçilmez oyunumuzda oluşturacağımız tüm nesneleri GameObject class’ından oluşturacağız.

public class GameObject
{
	public bool IsAlive;
	public Texture2D Texture;
	public Vector2 Position;
	public Vector2 Center;
	public Vector2 Velocity;
	public float Rotation;

	private Rectangle _TextureRectangle;
	public Rectangle TextureRectangle
	{
		get
		{
			_TextureRectangle.X = (int)Position.X;
			_TextureRectangle.Y = (int)Position.Y;

			return _TextureRectangle;
		}
	}

	public GameObject(Texture2D Texture)
	{
		this.IsAlive = false;
		this.Texture = Texture;
		this.Center = new Vector2(Texture.Width / 2, Texture.Height / 2);
		this.Position = Vector2.Zero;
		this.Velocity = Vector2.Zero;
		this.Rotation = 0;

		this._TextureRectangle = new Rectangle(0, 0, Texture.Width, Texture.Height);
	}
}

Yukarıdaki kodu incelediğimizde;

  • Oyun nesnesinin hala canlı olup olmadığını anlamak için IsAlive değişkeninin olduğunu
  • Oyun nesnesinin Texture‘unu almak için Texture nesnesinin olduğunu
  • Oyun nesnesinin ekrandaki yerini almak için Position değişkeninin olduğunu
  • Oyun nesnesinin kendi etrafında dönüş miktarını almak için Center ve Rotation değişkenlerinin olduğunu
  • Oyun nesnesinin hızını almak için Velocity değişkeninin olduğunu
  • Oyun nesnesinin ekranda kapladığı alanı bulmak için TextureRectangle özelliğinin olduğunu görürüz.

GameObject sınıfının constructor‘ı sadece bir Texture2D nesnesi alıyor ve bu parametreyi kendi iç değişkenlerinin değerlerini hesaplamada kullanıyor.

Artık GameLoop sınıfımızın class seviyesinde, Top nesnesi için, GameObject sınıfından değişken oluşturabiliriz.

public GameObject Top;

LoadContent() methodunda bu değişkenin atamasını yapalım;

Top = new GameObject(Content.Load<Texture2D>("Top"));

Update() methodunda Top nesnemizin yerini hesaplayalım;

KeyboardState ks = Keyboard.GetState();

if (ks.IsKeyDown(Keys.Left))
	Top.Position.X -= 5;
if (ks.IsKeyDown(Keys.Right))
	Top.Position.X += 5;

Aynı method içerisinde Top nesnemizin dönüş miktarını da hesaplayabiliriz; (Yukarı ve Aşağı tuşlarına basıldıkça 10 derece dönmesini sağlayacağız)

if (ks.IsKeyDown(Keys.Up))
	Top.Rotation += MathHelper.ToRadians(10);
if (ks.IsKeyDown(Keys.Down))
	Top.Rotation -= MathHelper.ToRadians(10);

MathHelper sınıfının static ToRadians fonksiyonu sayesinde, Top’umuzun dönme açısını radian cinsinden kolaylıkla hesaplayabiliyoruz.

Top‘umuzun dönme açısının -90 ile +90 dereceler arasında olduğundan ve ekrandan dışarı çıkmayıp, görünür olduğundan emin olalım;

if (Top.Position.X < 0)
	Top.Position.X = 0;
if (Top.Position.X > PENCERE_GENISLIK)
	Top.Position.X = PENCERE_GENISLIK;

if (Top.Rotation > MathHelper.ToRadians(90))
	Top.Rotation = MathHelper.ToRadians(90);
if (Top.Rotation < MathHelper.ToRadians(-90))
	Top.Rotation = MathHelper.ToRadians(-90);

Oyunun, Windows'ta başka bir pencereye geçilmesi esnasında (focus kaybetme) bekleme moduna geçmesini, tekrar oyuna dönüldüğünde ise (focus alma), kaldığı yerden devam etmesini sağlayalım;

Öncelikle sınıf seviyesindeki değişkenlerimize,

bool OYUN_DEVAM_EDIYOR = true;

ekliyoruz. Microsoft.Xna.Framework.Game sınıfından türetildiği için GameLoop sınıfının OnActivated ve OnDeactivated method’larını override edebiliriz.

OnDeactivated method’unda, oyun penceresinin focus kaybettiğini, OnActivated method’unda ise, oyun penceresinin focus aldığını anlayabiliriz.

protected override void OnActivated(object sender, EventArgs args)
{
  OYUN_DEVAM_EDIYOR = true;
  ArkaplanSes.Resume();
  base.OnActivated(sender, args);
}

protected override void OnDeactivated(object sender, EventArgs args)
{
  OYUN_DEVAM_EDIYOR = false;
  ArkaplanSes.Pause();
  base.OnDeactivated(sender, args);
}

Şu ana kadar oyunumuza hiç düşman eklemedik. Bir sonraki yazımda düşmanları ekleyeceğiz.

Top’umuzla da düşmanları vurup, puan kazanıyor olacağız.

XNA – Oyun Temelleri

22 Şubat 2010 Yorum yapılmamış

XNA ile oyun geliştirmeye başlamadan önce, ekrana nasıl çizim yapabileceğimizi öğrenmemiz gerekiyor.

Not : Buradan ileriye devam etmeden önce XNA – Başlangıç yazımı okumanızı tavsiye ederim.

Öncelikle, ihtiyacımız olacak iki görseli bilgisayarınıza kopyalamanız gerekiyor;

Fil Resmi - Arkaplan olarak kullanılacak Arı Resmi

Solution Explorer‘da Content üzerine sağ tuşla tıklayarak ari.png ve fil.png dosyalarını projeye ekleyelim.

GameLoop.cs dosyamızda class seviyesinde Texture2D tipinde iki değişken oluşturalım;

Texture2D ArkaPlan;
Texture2D Ari;

Daha sonra bu değişkenlere resimleri yükleyeceğiz. Aynı yere bir tane de Rectangle tipinde değişken oluşturalım.

Rectangle OyunPencere;

Bu değişkene ekranımızın boyutlarını yüklüyor olacağız.

LoadContent() method’unda bu değişkenlerin değerlerini atayalım;

OyunPencere = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);
ArkaPlan = Content.Load<Texture2D>("fil");
Ari = Content.Load<Texture2D>("ari");

GameLoop class’ının constructor‘ında oyunumuzun başlığını değiştirebiliriz;

public GameLoop()
{
	this.Window.Title = "XNA - Oyun Temelleri";
	graphics = new GraphicsDeviceManager(this);
	Content.RootDirectory = "Content";
}

Draw() method’unda resimlerin ekrana çizim işlerini yapacağız. Çizime işlemlerini Begin() ve End() methodları arasında yapmamız gerekiyor;

spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(ArkaPlan, OyunPencere, Color.White);
spriteBatch.Draw(Ari, Vector2D.Zero, Color.White);
spriteBatch.End();

Bu durumda uygulamayı çalıştırırsak, karşımıza şöyle bir ekran gelir;

XNA Oyun Temelleri

Şimdi arı resmini, klavye tuşlarını kullanarak ekranda hareket ettirelim. Öncelikle arı’nın ekrandaki konumunu tutan bir değişkene ihtiyacımız var, class seviyesindeki değişkenlere ekleyelim;

Vector2 Location = Vector2.Zero;

Draw() methodunda ari resmini çizdiğimiz satırı güncelleyelim;

spriteBatch.Draw(Ari, Location, Color.White);

Son olarak Update() method’umuzu güncelleyelim;

protected override void Update(GameTime gameTime)
{
	KeyboardState ks = Keyboard.GetState();

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

	if (ks.IsKeyDown(Keys.Up))
		Location.Y -= 3;
	if (ks.IsKeyDown(Keys.Down))
		Location.Y += 3;
	if (ks.IsKeyDown(Keys.Left))
		Location.X -= 3;
	if (ks.IsKeyDown(Keys.Right))
		Location.X += 3;

	base.Update(gameTime);
}

Gördüğünüz gibi, klavyede o anda basılı tuşları Keyboard.GetState() ile ks değişkenine yüklüyoruz, sonra basit karşılaştırmalar ile Location değişkenimizin X ve Y değerlerini değiştiriyoruz.

Draw() method’unda ari’yi çizeceğimiz yer olarak Location değişkenini verdiğimiz için, klavyeyi kullanarak ari’yi hareket ettirebildiğimizi görüyoruz.

XNA Oyun Temelleri

Oyunun kaynak kodlarını buradan indirebilirsiniz.