Bu yazımı okumadan önce XNA konusundaki diğer makalelerimi okumanızı öneririm.
Her zamanki gibi, öncelikle ihtiyacımız olacak görselleri vereyim;
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;</pre> 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.
Senior Software Engineer, @Microsoft
Ada ve Ege'nin babası ;)
Makale Adedi: 484