Arşiv

Etiketlenen yazılar ‘texture2d’

XNA ile Pong oyunu yazalım – 1

07 Mart 2010 Engin POLAT 5 comments

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

Her zamanki gibi, öncelikle ihtiyacımız olacak görselleri vereyim;

XNA - Pong Oyunu - Oyuncu 1 XNA - Pong Oyunu - Oyuncu 2 XNA - Pong Oyunu - Top

Ben kırmızı pedalı Oyuncu 1 için, mavi pedalı Oyuncu 2 için, yeşil kareyi ise Top olarak kullanacağım.

Visual Studio 2008 içerisinde yeni bir XNA projesi oluşturalım, Game1.cs‘in ismini GameLoop.cs ile değiştirelim ve class seviyesinde değişkenlerimizi tanımlayalım;

Texture2D Oyuncu1;
Texture2D Oyuncu2;
Texture2D Top;

Vector2 Oyuncu1Yer;
Vector2 Oyuncu2Yer;
Vector2 TopYer;

private int Oyuncu1Skor = 0;
private int Oyuncu2Skor = 0;
Vector2 TopYon;

private const int PENCERE_GENISLIK = 800;
private const int PENCERE_YUKSEKLIK = 600;
private const string PENCERE_BASLIK = "XNA - Pong Oyunu";
private const bool TAM_EKRAN = false;
private readonly Color ARKAPLAN_RENK = Color.Black;

GameLoop class‘ımızın contructor‘ına aşağıdaki kodları ekleyelim;

graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;
graphics.IsFullScreen = TAM_EKRAN;
this.Window.Title = PENCERE_BASLIK;

Şimdi LoadContent() method’unda görselleri hafızaya yükleyeceğimiz kodları ekleyelim;

Oyuncu1 = Content.Load<Texture2D>("Oyuncu1");
Oyuncu2 = Content.Load<Texture2D>("Oyuncu2");
Top = Content.Load<Texture2D>("Top");

Oyuncu1Yer = new Vector2((float)(graphics.GraphicsDevice.Viewport.Width * 0.07), (float)(graphics.GraphicsDevice.Viewport.Height / 2));
Oyuncu2Yer = new Vector2((float)(graphics.GraphicsDevice.Viewport.Width - (graphics.GraphicsDevice.Viewport.Width * 0.07)), (float)(graphics.GraphicsDevice.Viewport.Height / 2));
TopYer = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2);

TopYon = new Vector2(3, 3);

Draw() methodunda ekrana çizim işlerini yapalım;

spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

spriteBatch.Draw(Oyuncu1, Oyuncu1Yer, Color.White);
spriteBatch.Draw(Oyuncu2, Oyuncu2Yer, Color.White);
spriteBatch.Draw(Top, TopYer, Color.White);

spriteBatch.End();

Update() methodunda her iki oyuncunun ve top’un yerlerini hesaplayalım. Öncelikle klavyenin o andaki durumunu alalım;

KeyboardState ks = Keyboard.GetState();

Hangi tuşların basılı olduğunu kontrol edelim;

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

if (ks.IsKeyDown(Keys.Up))
	Oyuncu1Yer.Y -= 3;
if (ks.IsKeyDown(Keys.Down))
	Oyuncu1Yer.Y += 3;

if (Oyuncu1Yer.Y < 0)
	Oyuncu1Yer.Y = 0;
if (Oyuncu1Yer.Y > PENCERE_YUKSEKLIK - Oyuncu1.Height)
	Oyuncu1Yer.Y = PENCERE_YUKSEKLIK - Oyuncu1.Height;

if (ks.IsKeyDown(Keys.E))
	Oyuncu2Yer.Y -= 3;
if (ks.IsKeyDown(Keys.D))
	Oyuncu2Yer.Y += 3;

if (Oyuncu2Yer.Y < 0)
	Oyuncu2Yer.Y = 0;
if (Oyuncu2Yer.Y > PENCERE_YUKSEKLIK - Oyuncu2.Height)
	Oyuncu2Yer.Y = PENCERE_YUKSEKLIK - Oyuncu2.Height;

Top‘un ekrandan dışarı çıkmaması için, ekranın üstüne veya altına eriştiğinde, yönünü değiştirecek kodu ekleyelim;

if ((TopYer.Y < 0) || (TopYer.Y > PENCERE_YUKSEKLIK - Top.Height))
	TopYon.Y *= -1;
if ((TopYer.X < 0) || (TopYer.X > PENCERE_YUKSEKLIK - Top.Width))
	TopYon.X *= -1;

Şimdi Oyuncu 1, Oyuncu 2 ve Top için konum ve boyut bilgilerini tutacağımız Rectangle değişkenlerini tanımlayalım;

Rectangle Oyuncu1Rect = new Rectangle((int)Oyuncu1Yer.X, (int)Oyuncu1Yer.Y, Oyuncu1.Width, Oyuncu1.Height);
Rectangle Oyuncu2Rect = new Rectangle((int)Oyuncu2Yer.X, (int)Oyuncu2Yer.Y, Oyuncu2.Width, Oyuncu2.Height);
Rectangle TopRect = new Rectangle((int)TopYer.X, (int)TopYer.Y, Top.Width, Top.Height);

Yapmamız gereken, Top‘un Oyuncu 1 veya Oyuncu 2 ile kesiştiği durumda yönünü ters çevirmek. Ayrıca eğer Oyuncu 1 veya Oyuncu 2‘nin arkasına geçerse diğer oyuncunun skor‘unu bir artırmak ve Top‘un yerini sıfırlamak;

if (TopRect.Intersects(Oyuncu1Rect) || TopRect.Intersects(Oyuncu2Rect))
	TopYon.X *= -1;

if (TopYer.X < Oyuncu1Yer.X)
{
	Oyuncu2Skor++;
	TopYer.X = graphics.GraphicsDevice.Viewport.Width / 2;
}

if (TopYer.X > Oyuncu2Yer.X)
{
	Oyuncu1Skor++;
	TopYer.X = graphics.GraphicsDevice.Viewport.Width / 2;
}

TopYer += TopYon;

Şu anda elimizde oynayabileceğimiz bir Pong oyunu var. Her iki oyuncu için skor bilgisini de tutuyoruz. Fakat skor’u ekrana yazdırmadık.

Ekrana skor yazdırma işini bir sonraki yazıya bırakıyorum. Oyunun kodlarını da bir sonraki yazıda veriyor olacağım.

XNA ile ekranda UzayGemisi yönetmek

06 Mart 2010 Engin POLAT 1 Yorum

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

Öncelikle ihtiyacınız olacak iki görseli buradan indirebilirsiniz;

XNA - Oyun Programlama - Uzay Arkaplanı XNA - Oyun Programlama - Uzay Gemisi

Yapmak istediğimiz;

  • 800 x 600 pencere içerisinde arkaplanda Uzay.jpg görselini göstermek
  • Pencerenin ortasına UzayGemisi.png dosyasını konumlandırmak
  • Klavyenin tuşlarına görevler atayarak, UzayGemisi‘ni Uzay içerisinde yönetmek

Hemen başlayalım, ilk olarak yeni bir XNA projesi oluşturalım. Game1.cs dosyasının adını GameLoop.cs olarak değiştirelim.

Uzay.jpg ve UzayGemisi.png dosyalarını Content içerisine sürükleyip bırakalım. GameLoop.cs dosyasını açarak kod yazmaya başlayalım;

Sabitlerimizi class seviyesinde const ve readonly field’larda tanımlayalım;

private const int PENCERE_GENISLIK = 800;
private const int PENCERE_YUKSEKLIK = 600;
private const string PENCERE_BASLIK = "XNA - Uzay'da UzayGemisi Yönetelim";
private const bool TAM_EKRAN = false;
private readonly Color ARKAPLAN_RENK = Color.Black;

GameLoop class‘ının constructor‘ında bu sabitleri kullanalım;

graphics.PreferredBackBufferWidth = PENCERE_GENISLIK;
graphics.PreferredBackBufferHeight = PENCERE_YUKSEKLIK;
graphics.IsFullScreen = TAM_EKRAN;
this.Window.Title = PENCERE_BASLIK;

Uzay görselimizi 800 x 600 boyutlarındaki oyun penceremize sığdırmak için class seviyesinde Rectangle tipinde bir değişken tanımlayalım, Uzay ve UzayGemisi görsellerimiz için de birer tane Texture2D tipinde değişken tanımlayalım;

Rectangle Pencere;
Texture2D Uzay;
Texture2D UzayGemisi;

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

Pencere = new Rectangle(0, 0, PENCERE_GENISLIK, PENCERE_YUKSEKLIK);
Uzay = Content.Load<Texture2D>("Uzay");
UzayGemisi = Content.Load<Texture2D>("UzayGemisi");

Artık Uzayımızı ve UzayGemimizi oyun penceresine çizebiliriz. Ama madem uzay gemisini klavye tuşları ile yönetmek istiyoruz, o zaman uzay gemisinin kendi çevresinde dönebilmesini de sağlamamız gerekir.

Eğer bunu yapmazsak, Yukarı tuşu ile yukarı giden uzay gemisi, Aşağı tuşu ile aşağı gelirken yönünü düzeltmez, geri geri geliyormuş gibi gözükür. Hatta yanlara ve çağrazlara giderken iyice anlamsız görünmeye başlar.

Öncelikle uzay gemisinin o anda oyun penceresinin neresinde olduğunu tutacağımız Vector2 sınıfında bir değişkene class seviyesinde ihtiyacımız var, ayrıca uzay gemisinin gideceği yöne göre yönelmesi için, iki değişkene daha ihtiyacımız olacak;

Vector2 Konum = Vector2.Zero;
Vector2 Merkez;
float Yonelme = 0;

Uzay gemisinin doğru bir yönelme yapabilmesi için, ağırlık merkezini doğru vermemiz gerekiyor, LoadContent() methoduna aşağıdaki kodu ekleyelim;

Merkez = new Vector2(UzayGemisi.Width / 2, UzayGemisi.Height / 2);

Önce Draw() methodumuzu yazalım;

GraphicsDevice.Clear(ARKAPLAN_RENK);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

spriteBatch.Draw(Uzay, Pencere, Color.White);
spriteBatch.Draw(UzayGemisi, Konum, null, Color.White, Yonelme, Merkez, 1, SpriteEffects.None, 0);

spriteBatch.End();
base.Draw(gameTime);

Son olarak Update() methodumuzu yazalım;

Öncelikle klavyenin o andaki durumunu tutacağımız değişkenimizi tanımlıyoruz;

KeyboardState ks = Keyboard.GetState();

Eğer Escape tuşuna basılıyorsa, oyunda çıkıyoruz;

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

Eğer hem Yukarı, hem de Sağa tuşlarına basılıyorsa, uzay gemisinin X ve Y koordinatlarında güncellemeler yapıp, yönelmesini 45 derecenin radian karşılığına eşitliyoruz;

if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y -= 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(45);
}

MathHelper.ToRadians() parametre olarak derece cinsinden değer alır ve geriye float cinsinden radian döner.

Update() methodunun geri kalanında yön tuşlarına göre uzay gemisinin koordinatlarını ve yönelmesini güncelliyoruz;

if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y -= 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(45);
}
else if (ks.IsKeyDown(Keys.Up) && ks.IsKeyDown(Keys.Left))
{
	Konum.Y -= 3;
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(315);
}
else if (ks.IsKeyDown(Keys.Down) && ks.IsKeyDown(Keys.Right))
{
	Konum.Y += 3;
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(135);
}
else if (ks.IsKeyDown(Keys.Down) && ks.IsKeyDown(Keys.Left))
{
	Konum.Y += 3;
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(225);
}
else if (ks.IsKeyDown(Keys.Up))
{
	Konum.Y -= 3;
	Yonelme = MathHelper.ToRadians(0);
}
else if (ks.IsKeyDown(Keys.Down))
{
	Konum.Y += 3;
	Yonelme = MathHelper.ToRadians(180);
}
else if (ks.IsKeyDown(Keys.Left))
{
	Konum.X -= 3;
	Yonelme = MathHelper.ToRadians(270);
}
else if (ks.IsKeyDown(Keys.Right))
{
	Konum.X += 3;
	Yonelme = MathHelper.ToRadians(90);
}

Son olarak Update() methodunda uzay gemisinin pencereden dışarı çıkmasını engelleyecek kontrol kodlarını da yazıyoruz;

if (Konum.X < 0)
	Konum.X = 0;
if (Konum.X > PENCERE_GENISLIK - UzayGemisi.Width)
	Konum.X = PENCERE_GENISLIK - UzayGemisi.Width;
if (Konum.Y < 0)
	Konum.Y = 0;
if (Konum.Y > PENCERE_YUKSEKLIK - UzayGemisi.Height)
	Konum.Y = PENCERE_YUKSEKLIK - UzayGemisi.Height;

“Oyun” projemizin kodlarını buradan bilgisayarınıza indirebilirsiniz.

Projeyi çalıştırdığınızda aşağıdaki gibi bir sonuç almanız lazım;

XNA - Uzay Oyunu Sonuç Penceresi

XNA – Oyun Temelleri

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.