GraphicsDeviceManager | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar GraphicsDeviceManager

XNA Oyunu / Vahşi Batı

25 June 2012 3 yorum

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

Her zamanki gibi önce görseller;

XNA Oyun - Vahşi Batı - Cursor XNA Oyun - Vahşi Batı - Tombstone XNA Oyun - Vahşi Batı - Horse XNA Oyun - Vahşi Batı - Background

Bir tane silah sesi dosyamız var;

Magnum Gunshot

Bir tane de Sprite Font dosyamız var;

SkorFont.spritefont ismini verdiğim dosyanın, “yorum satırları kaldırılmış halini” aşağıdaki gibi düzenledim;

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

Başlayalım oyunumuzu yazmaya; VahsiBati projemizi oluşturduktan ve Game1.cs‘in ismini GameLoop.cs olarak değiştirdikten sonra, Target isminde bir sınıf oluşturalım;

public class Target
{
	public const int FrameWidth = 104;

	public Vector2 Position;

	private Rectangle _Area = new Rectangle(0, 0, FrameWidth, FrameWidth);
	public Rectangle Area
	{
		get
		{
			_Area.X = (int)Position.X;
			_Area.Y = (int)Position.Y;

			return _Area;
		}
	}

	public bool ToLeft;

	public float RunSpeed;

	public int FrameIndex;

	public SpriteEffects SpriteEffect;

	public TimeSpan LastFrameChange = TimeSpan.Zero;

	public TimeSpan FrameChangeBuffer = TimeSpan.Zero;

	public bool IsDead = false;
}

Target sınıfı sayesinde, ekrana getireceğimiz hedef‘lerin ekranın neresinden çıkıp, hangi yöne doğru gideceğini bileceğiz, hedefin vurulup/vurulmadığını bileceğiz, çarpışma testi yapabilmek için ekranda kapladığı alanı bileceğiz, hızını bileceğiz, ayrıca hedef‘imizin harekete sahip olmasını sağlayabileceğiz (bknz; XNA ile Karakter Hareketi)

GameLoop.cs dosyasına geri dönelim, ilk önce arkaplanımızın hareketli olması için (bknz; XNA ile Hareketli Arkaplan) sınıf seviyesinde şu değişkenleri tanımlayalım;

Rectangle Screen;

Texture2D Background1;
Texture2D Background2;

Rectangle Background1Position;
Rectangle Background2Position;

GameLoop constructor‘ında Screen değişkenine;

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

LoadContent method’unda Background değişkenlerine değer atayalım;

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

Background1Position = new Rectangle(0, 0, Background1.Width, Background1.Height);
Background2Position = new Rectangle(Background1.Width, 0, Background2.Width, Background2.Height);

Update method’unda Background‘un yerini güncelleyelim;

Background1Position.X -= 1;
Background2Position.X -= 1;

if (Background1Position.X < -Background1.Width)
{
	Background1Position.X = Background2Position.X + Background2.Width;
}

if (Background2Position.X < -Background2.Width)
{
	Background2Position.X = Background1Position.X + Background1.Width;
}

Son olarak Draw method'unda Background'u ekrana çizelim;

spriteBatch.Begin();

spriteBatch.Draw(Background1, Background1Position, Color.White);
spriteBatch.Draw(Background2, Background2Position, Color.White);

spriteBatch.End();

Ekrana işaretçi çizdirmek için, sınıf seviyesinde aşağıdaki değişkenleri ekleyelim;

Texture2D Cursor;

Vector2 CursorPosition = Vector2.Zero;
Vector2 CursorCenter = Vector2.Zero;

Rectangle CursorZone;

MouseState ms;
MouseState pms;

GameLoop constructor‘ında CursorZone değişkenini dolduralım;

CursorZone = new Rectangle(0, 0, 5, 5);

LoadContent method‘unda Cursor değişkenlerine değer atayalım;

Cursor = Content.Load<Texture2D>("Cursor");
CursorCenter = new Vector2(Cursor.Width / 2, Cursor.Height / 2);

Update method‘unda işaretçinin ekranda görüntüleneceği yeri hesaplayalım;

ms = Mouse.GetState();

CursorPosition = new Vector2(ms.X, ms.Y);

pms = ms;

Draw method’unda Cursor nesnemizi ekrana çizdirelim;

spriteBatch.Draw(Cursor, CursorPosition, null, Color.White, 0f, CursorCenter, 0.6f, SpriteEffects.None, 0f);

Sınıf seviyesinde aşağıdaki değişkenleri tanımlayalım;

Texture2D Horse;

Texture2D Tombstone;

SpriteFont SkorFont;
Vector2 SkorPosition;

SoundEffect Gunshot;

Random r;

int Score = 0;

Böylece hedef‘in görselini, vurulduğunda dönüşeceği mezarlık görselini, ateş etme sırasında duyulacak silah sesini, kaç hedef vurduğumuzu tutabileceğimiz değişkenlerimiz tanımlamış olduk.

Constructor‘da r değişkenine değer ataması yapalım;

r = new Random();

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

Horse = Content.Load<Texture2D>("Horse");
Tombstone = Content.Load<Texture2D>("Tombstone");

SkorFont = Content.Load<SpriteFont>("SkorFont");
SkorPosition = new Vector2(20, 10);

Gunshot = Content.Load<SoundEffect>("Magnum");

Henüz ekranda hedefleri göremesek‘te oyunumuzun önemli kısımlarının hazırlıklarını tamamladık. Artık hedef listesini tanımlayabilir, Update ve Draw method’larında kullanabiliriz. Sınıf seviyesinde aşağıdaki değişkenleri tanımlayalım;

TimeSpan LastHorseSpawn = TimeSpan.Zero;
TimeSpan SpawnHorseBuffer = TimeSpan.FromSeconds(3);

List<Target> TargetList = new List<Target>();

Update method’unda son hedef üretilme zamanından itibaren yeterli süre geçmişse, yeni hedef oluşturmamız lazım;

if (gameTime.TotalGameTime - LastHorseSpawn > SpawnHorseBuffer)
{
	Target t = new Target();
	t.FrameIndex = 0;
	t.ToLeft = r.Next(0, 2) == 0;
	t.RunSpeed = Convert.ToSingle(r.Next(20, 70)) / 10;
	t.FrameChangeBuffer = TimeSpan.FromMilliseconds(100 + -t.RunSpeed);

	if (t.ToLeft)
	{
		t.Position = new Vector2(graphics.PreferredBackBufferWidth - t.Area.Width, r.Next(200, 400));
		t.SpriteEffect = SpriteEffects.FlipHorizontally;
	}
	else
	{
		t.Position = new Vector2(0, r.Next(200, 400));
		t.SpriteEffect = SpriteEffects.None;
	}

	TargetList.Add(t);

	LastHorseSpawn = gameTime.TotalGameTime;
}

Hedef’in ekranın solundan sağına/sağından soluna gideceğine rastgele karar veriyoruz (ToLeft alanı sayesinde)

Hedef’in ekranda koşma hızına rastgele karar veriyoruz (RunSpeed alanı sayesinde)

Update method’unda hedef listesindeki hedeflerin hala ekranda göründüğünü kontrol ediyoruz, eğer ekrandan çıkmışlarsa hedef listesinden de çıkartıyoruz. Ekranda kalan hedefleri, koşma hızları kadar koşturuyoruz;

foreach (var t in TargetList)
{
	if (!Screen.Intersects(t.Area))
	{
		TargetList.Remove(t);
		break;
	}

	if (gameTime.TotalGameTime - t.LastFrameChange > t.FrameChangeBuffer)
	{
		t.FrameIndex += 1;
		t.LastFrameChange = gameTime.TotalGameTime;
	}

	if (t.FrameIndex > 3)
	{
		t.FrameIndex = 0;
	}

	if (t.ToLeft)
	{
		t.Position.X -= t.RunSpeed;
	}
	else
	{
		t.Position.X += t.RunSpeed;
	}
}

Update method’unda ayrıca, mouse‘un sol tuşuna basıldığında ateş edilmesini sağlamamız gerekiyor. Öncelikle sol tuşa ilk basıldığı anı buluyoruz, silah sesi çıkartıyoruz, hedef listesindeki hedefleri kontrol ediyoruz. Eğer vurulan hedef varsa, mezarlık görseline döndürüyoruz, Skor‘umuzu 1 arttırıyoruz;

if (ms.LeftButton == ButtonState.Pressed && pms.LeftButton == ButtonState.Released)
{
	Gunshot.Play();

	CursorZone.X = ms.X - 2;
	CursorZone.Y = ms.Y - 2;

	foreach (var t in TargetList)
	{
		if (!t.IsDead && t.Area.Intersects(CursorZone))
		{
			Score++;
			t.Position += new Vector2(20, 20);
			t.IsDead = true;
			t.ToLeft = true;
			t.RunSpeed = 1;
			break;
		}
	}
}

Son olarak Draw method’unda, hala hedef listesinde olan hedefleri ve skorumuzu ekrana çizdirmemiz gerekiyor;

foreach (var t in TargetList)
{
	if (t.IsDead)
	{
		spriteBatch.Draw(Tombstone, t.Position, Color.White);
	}
	else
	{
		spriteBatch.Draw(Horse, t.Position, new Rectangle(t.FrameIndex * Target.FrameWidth, 0, Target.FrameWidth, Target.FrameWidth), Color.White, 0f, Vector2.Zero, Vector2.One, t.SpriteEffect, 0);
	}
}

spriteBatch.DrawString(SkorFont, "Skor : " + Score, SkorPosition + Vector2.One, Color.Black);
spriteBatch.DrawString(SkorFont, "Skor : " + Score, SkorPosition, Color.White);

İşte Vahşi Batı oyunundan bir ekran görüntüsü. Oyunun kaynak kodlarını buradan indirebilirsiniz.

XNA Oyun : Vahşi Batı

XNA Oyunu / Meyve Veren Ağaç

15 April 2012 Yorum yapılmamış

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

Önce görseller;

XNA - Meyve Veren Ağaç - Araba XNA - Meyve Veren Ağaç - Adam XNA - Meyve Veren Ağaç - Sepet XNA - Meyve Veren Ağaç - Armut XNA - Meyve Veren Ağaç - Uzum XNA - Meyve Veren Ağaç - Elma XNA - Meyve Veren Ağaç - Portakal XNA - Meyve Veren Ağaç - Seftali XNA - Meyve Veren Ağaç - Cilek XNA - Meyve Veren Ağaç - Kavun XNA - Meyve Veren Ağaç - Tas XNA - Meyve Veren Ağaç - Muz XNA - Meyve Veren Ağaç - Ağaç Arkaplan

Bir tane arkaplan ses dosyamız var;

Arkaplan Müziği

Bir tane de Sprite Font dosyamız var;

SkorFont.spritefont ismini verdiğim dosyanın, “yorum satırları kaldırılmış halini” aşağıdaki gibi düzenledim;

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

Başlayalım oyunumuzu yazmaya; MeyveVerenAgac 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 BackgroundLoop;

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

BackgroundLoop = Content.Load<SoundEffect>("BackgroundLoop").CreateInstance();

BackgroundLoop.Volume = 0.2f;
BackgroundLoop.IsLooped = true;
BackgroundLoop.Play();

Ses dosyası ile yaptığımız bu işlemleri XNA ile Pong oyunu yazalım – 2 ve XNA Oyun / Çanakkale Geçilmez – 1 yazılarımdan hatırlayacaksınız.

XNA Oyun / Çanakkale Geçilmez – 1 oyunumdan hatırlayacağınız GameObject sınıfını oluşturalım;

public enum GameObjectList
{
	Background,
	Basket,
	Random,
	Man,
	Car,
	Pear,
	Strawberry,
	Apple,
	Melon,
	Banana,
	Orange,
	Peach,
	Rock,
	Grape
}

public class GameObject : DrawableGameComponent
{
	SpriteBatch spriteBatch;

	public GameObjectList GameObjectType;

	Texture2D ObjectTexture;

	Vector2 ObjectPosition;

	Random r;

	MouseState ms;

	float FallSpeed = 0f;

	public Rectangle ObjectRectangle;

	public GameObject(Game game, GameObjectList GameObjectType) : base(game)
	{
		r = new Random();

		if (GameObjectType == GameObjectList.Random)
		{
			this.GameObjectType = (GameObjectList)r.Next(3, 14);
		}
		else
		{
			this.GameObjectType = GameObjectType;
		}

		FallSpeed = (float)(r.Next(1, 4) + r.NextDouble());
	}

	public override void Initialize()
	{
		base.Initialize();
	}

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

		switch (this.GameObjectType)
		{
			case GameObjectList.Background:
				ObjectTexture = this.Game.Content.Load<Texture2D>("AgacArkaplan");

				ObjectPosition = Vector2.Zero;
				break;
			case GameObjectList.Man:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Adam");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Car:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Araba");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Pear:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Armut");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Strawberry:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Cilek");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Apple:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Elma");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Melon:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Kavun");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Banana:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Muz");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Orange:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Portakal");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Peach:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Seftali");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Basket:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Sepet");

				ObjectPosition = new Vector2(350, 520);
				break;
			case GameObjectList.Rock:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Tas");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
			case GameObjectList.Grape:
				ObjectTexture = this.Game.Content.Load<Texture2D>("Uzum");

				ObjectPosition = new Vector2(r.Next(0, 800), 10);
				break;
		}

		ObjectRectangle = new Rectangle((int)ObjectPosition.X, (int)ObjectPosition.Y, ObjectTexture.Width, ObjectTexture.Height);

		base.LoadContent();
	}

	public override void Update(GameTime gameTime)
	{
		if (GameObjectType == GameObjectList.Basket)
		{
			ms = Mouse.GetState();

			ObjectPosition.X = ms.X;

			ObjectRectangle.X = ms.X;
		}
		else if (GameObjectType != GameObjectList.Background)
		{
			ObjectPosition.Y += FallSpeed;

			ObjectRectangle.Y = (int)ObjectPosition.Y;
		}

		base.Update(gameTime);
	}

	public override void Draw(GameTime gameTime)
	{
		spriteBatch.Begin();

		spriteBatch.Draw(ObjectTexture, ObjectPosition, Color.White);

		spriteBatch.End();

		base.Draw(gameTime);
	}
}

Yeni eklediğimiz GameObjectList enum sayesinde, GameObject sınıfından ürettiğimiz her değişken farklı bir görünüşe ve davranışa sahip olabiliyor. (Örneğin, puan alacağımız üzüm-çilek-kavun gibi meyveler veya puan kaybedeceğimiz taş-araba-insan gibi nesneler)

GameObject sınıfını Microsoft.Xna.Framework namespace‘inde yer alan DrawableGameComponent sınıfından türetiyoruz.

DrawableGameComponent sınıfından türettiğimiz için, GameObject sınıfının kendi LoadContent, Update ve Draw method’ları oluyor.

LoadContent method’unda, ilgili görseli seçip, hafızaya yüklüyoruz. Update method’unda, eğer nesne Sepet veya Arkaplan değilse, rastgele hızda aşağı düşürüyoruz. Eğer nesne Sepet ise, Mouse tarafından kontrol edilmesini sağlıyoruz;

if (GameObjectType == GameObjectList.Basket)
{
	ms = Mouse.GetState();

	ObjectPosition.X = ms.X;

	ObjectRectangle.X = ms.X;
}

Draw method’unda ise, basitçe ilgili nesneyi ekrana çizdiriyoruz.

GameLoop sınıfına aşağıdaki değişkenleri ekleyelim;

GameObject Basket;
SpriteFont ScoreFont;
Vector2 ScorePosition;

GameObject sınıfınının constructor‘ına aşağıdaki satırları ekleyelim;

Basket = new GameObject(this, GameObjectList.Basket);

this.Components.Add(Basket);

this.Components.Add(new GameObject(this, GameObjectList.Background));

LoadContent method’una aşağıdaki kodları ekleyelim;

ScoreFont = Content.Load<SpriteFont>("SkorFont");
ScorePosition = new Vector2(30, 560);

Rastgele nesne oluşturup, ağaçtan aşağı düşürmeden önce, Son Nesne Oluşturma Zamanı, Nesne Oluşturma Zaman Aralığı gibi değerleri saklayabileceğimiz değişkenlere ihtiyacımız olacak, hemen GameLoop sınıfının içerisinde tanımlayalım;

TimeSpan PreviousFallTime;
TimeSpan FallBufferTime = TimeSpan.FromMilliseconds(1000);

Böylece, her saniye yeni bir nesne oluşturmak için ihtiyaç duyacağımız tüm değişkenleri tanımlamış olduk.

Update method’una aşağıdaki kodları yazalım;

if (gameTime.TotalGameTime - PreviousFallTime > FallBufferTime)
{
	this.Components.Add(new GameObject(this, GameObjectList.Random));

	PreviousFallTime = gameTime.TotalGameTime;
}

for (int iLoop = 0; iLoop < this.Components.Count; iLoop++)
{
	GameObject CurrentComponent = (GameObject)this.Components[iLoop];

	if (CurrentComponent.GameObjectType != GameObjectList.Background && CurrentComponent.GameObjectType != GameObjectList.Basket)
	{
		if (Basket.ObjectRectangle.Intersects(CurrentComponent.ObjectRectangle))
		{
			if (CurrentComponent.GameObjectType == GameObjectList.Rock)
			{
				Skor -= 1;
			}
			else if (CurrentComponent.GameObjectType == GameObjectList.Man)
			{
				Skor -= 2;
			}
			else if (CurrentComponent.GameObjectType == GameObjectList.Car)
			{
				Skor -= 3;
			}
			else
			{
				Skor += 1;
			}

			this.Components.Remove(CurrentComponent);
		}
	}
}

Geriye sadece Draw method'u kaldı;

spriteBatch.Begin();

spriteBatch.DrawString(ScoreFont, "Skor : " + Skor, ScorePosition + Vector2.One, Color.Black);
spriteBatch.DrawString(ScoreFont, "Skor : " + Skor, ScorePosition, Color.White);

spriteBatch.End();

Skor bilgisini, bir beyaz, bir siyah renkle, iki defa çizdiriyoruz. İkinci çizimi 1px farklı konuma çizdirdiğimiz için, yazı ekranda sanki gölgesi varmış gibi gözüküyor.

İşte Meyve Veren Ağaç oyunundan bir ekran görüntüsü. Oyunun kaynak kodlarını buradan indirebilirsiniz.

Meyve Veren Ağaç oyunun bitmiş hali

XNA ile Karakter Hareketi

11 July 2011 4 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 – Kısa sorular, Kısa cevaplar

28 June 2011 2 yorum

Mouse ikonumu bulamıyorum?

Evet, varsayılan olarak XNA, oyun penceresi içerisinde mouse ikonunu gizler. Eğer mouse’u görmek istiyorsanız;

this.IsMouseVisible = true;

kodunu eklemeniz gerekir.

Oyunu farklı çözünürlükte çalıştırmak istiyorum

XNA ile oyun geliştirmeye çalışan her programcının çok kısa süre sonra merak ettiği bir sorudur bu.

Çözüm;

public Game1()
{
	graphics = new GraphicsDeviceManager(this);

	Content.RootDirectory = "Content";

	/// Oyun penceresinin çözünürlüğünü 1920x1080 ayarlar
	this.graphics.PreferredBackBufferWidth = 1920;
	this.graphics.PreferredBackBufferHeight = 1080;
}

Not : Bu konu ile ilgili XNA – Oyun ekranının boyutlarını belirlemek yazımı okumanızı tavsiye ederim.

Oyunumu tam ekran oynatmak istiyorum

Çözünürlüğü değiştirdikten hemen sonra, tam ekran oyun nasıl oynatılır? sorusu gelir;

protected override void Initialize()
{
	/// Eğer tam ekran değilse, tam ekran moduna geç!
	if (!graphics.IsFullScreen)
	{
		graphics.ToggleFullScreen();
	}

	base.Initialize();
}

Not : Bu konu ile ilgili XNA – Oyun ekranının boyutlarını belirlemek yazımı okumanızı tavsiye ederim.

Oyun penceremin aktif olup/olmadığını nasıl anlarım?

Windows oyunları o anda çalışan tek uygulama olmayabilirler. Oyuncular, oyun oynarken, email adreslerini kontrol etmek, internette bir kelime araştırmak veya diğer oyuncular ile farklı ortamlarda sohbet etmek isteyebilirler.

Oyun penceresinden başka bir uygulamaya geçtiklerinde (yani oyun penceresi focus kaybettiğinde) oynadıkları oyunun durmasını (pause moduna geçmesini) isterler.

Oyun penceresinin Active veya InActive olduğunu kontrol etmemiz, Active değilse, Pause moduna geçmemiz gerekmektedir;

Not : Bu konu ile ilgili XNA Oyunu / Çanakkale Geçilmez – 1 yazımı okumanızı tavsiye ederim.

protected override void Update(GameTime gameTime)
{
	if (this.IsActive)
	{
		/// Sadece oyun penceresi aktif iken yapılması gereken işleri
		/// buraya yazıyoruz

		/// Joystik, klavye, mouse hareketlerini algılamak
		/// Yapay zeka görevlerini yürütmek gibi
	}

	base.Update(gameTime);
}

Oyun penceresinin başlığını nasıl değiştiririm?

protected override void Initialize()
{
	this.Window.Title = "Oyun oynamak içindir!";

	base.Initialize();
}