Visual Studio ortamında yeni bir oyun projesi oluşturduğumuzda karşımıza gelen Game1 isimli C Sharp sınıfına ve Program sınıfımıza göz atalım.Bu yazımızda bu sınıflarımız ve birlikte gelen foksiyonlar hakkında bilgi vermeye çalışacağım.
İsmini bizim belirlediğimiz projenin alan adı(1) altında gelen Game1 ve Program isimli sınıflar ile içerik yönetim klasorü(2) karşımıza hazır olarak geliyorlar.
Öncelikle Program sınıfımızı anlatarak onu bitirelim.Çünkü bizler için hakkında bahsedecek fazla birşey bulunmamaktadır.Projemizin ana sınıfı olup Main fonksiyonu bünyesinde barındırdığından uçaklarımızın kalkış üssü olarak adlandırabileceğimiz sınıftır.Main fonksiyonu içerisinde oyunla ilgili güncelleme,çizim işlemlerinin sürekli olarak devam ettiği bir mekanizmayı içeren Game1 sınıfımızın örneğini oluşturarak görevini tamamlar.Artık bundan sonrası Game1 sınıfının çarklarıyla dönmektedir.
Game1 sınıfı uzantısı Microsoft.Xna.Framework.Game olan yani Game isimli bir sınıftan miras almaktadır.Şimdilik Game sınıfında bizim için birçok ayarlamaların yapıldığını
söylememiz yeterli olacaktır diye düşünüyorum.Game1 sınıfıyla birlikte Initialize,LoadContent,UnloadContent,Update,Draw isimli fonksiyonlar geliyor.(Tabi bunlar XNA Framework 3.1 haliyle mevcut.)
Bu fonksiyonlar hakkında konuşmaya başlamadan önce kısa olarak basit bir oyun akış döngüsüne değinmek istiyorum.Öncelikle bütün gerekli başlangıç ayarlamalarını(grafik vb) tamamlayıp oyun içinde kullanacağımız kaynakları yükleriz.Bu işlemlerin ardından oyunumuzun en önemli kısmı Game Loop(3) dediğimiz sürekli bazı işlemlerin tekrarlanmasının gerektiği oyun döngüsüne gireriz.Her seferinde AI(4),Collision Detection(5),hareketler,kullanıcı girişleri(),sesler,görsellerin çizdirilmesi işlemleri tekrar tekrar yapılırlar.Elbette bütün bu işlemler gene bu döngü içerisinde takip edilip,yazılımcının belirlediği koşullar sağlanana kadar devam eder.Bununla kastımız örneğin belli bir hak(6) kaybı yaşandığında oyunun sonlanması gibi.İşte aklımıza gelebilecek çoğu oyun içi gerekli düzenlemelerin yapıldığı,kontrol mekanizmalarının çalıştığı kısımdır diyebiliriz.Döngünün sonlanması durumunda ise kullandığımız donanım kaynaklarını rahat bırakıp annemizin oğlum artık kalk şu bilgisayarın başından diye seslendiği ana tanıklık etmemiz mümkündür.
Game1 sınıfımızda ilk olarak gözümüze çarpan SpriteBatch ve GraphicsDeviceManager sınıflarının nesneleridir.
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Game1 sınıfının yapıcı fonksiyonunda (7) graphics nesnemiz ve bir önceki yazımızda anlattığımız Content Pipeline sistemi için kök dizini(8) tanımlanmaktadır.
public Game1( )
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
Burada görünen Content nesnesi ContentManager sınıfından oluşturulmuş olup hazır olarak gelmektedir.spriteBatch nesnesi ise yazı yazdırmak veya 2D imaj dosyalarını oyun penceresinde görüntüleme gibi amaçlarla kullanılmaktadır.
GraphicsDeviceManager sınıfından nesnemiz graphics ise oyunlardan sorumlu donanım kartımız olan ekran kartı ile iletişim kurmamızı sağlayan,gerekli grafiksel ayarlamaları yapabilmemize olanak sağlayan bir alandır.Bunlar Game1 sınıfımızla beraber gelen başka sınıflara ait örnekler olup gene bu sınıflardan kendimize ait yeni nesneler türetmemiz mümkündür.
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Game1( )
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
Game1 sınıfında bundan sonra inceleyeceğimiz fonksiyon Initialize olup Game1 sınıfı için gerekli servislerin,grafik olmayan vb şeylerin yüklendiği (override edilmiş bir fonksiyon,Game sınıfında aynı isimdeki fonksiyonun ayarlarını kullanmaktadır.Ek olarak ise örneğin ekran boyutlarını belli ölçülerde yapılandırmak istiyorsunuz,Program sınıfında game.Run( ) ile kalkışa geçtikten sonra sadece bir kere çalışacak olan bu fonksiyonu kullanabilirsiniz)Oyun döngüsünden bahsetmiştik.O döngüye girmeden önce ayarlamaların gerçekleştiği bu metot içerisinde ses içeriğinin yüklenmesi gibi işlemlerde yapabiliriz.Birde LoadContent metotu var ve içeriğimizin tümünü yükleyebilmemize olanak tanıyor.Initialize metotu tarafından bir kere çağrılan bu fonksiyon grafik dosyalarının yüklenme işlemini gerçekleştirebileceğimiz bir metottur.Yukarıda anlattığımız spriteBatch örneğimizi de burada tanımlıyoruz.
protected override void LoadContent( )
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
UnloadContent metotu,oyun bitirilirken içerik dosyaları için kullandığımız belleği boşaltmaya yarar.
protected override void UnloadContent( )
{
// TODO: Unload any non ContentManager content here
}
Bu metotlarımızın ardından geliyoruz Game Loop dediğimiz kısımda ki en önemli iki fonksiyona:Update ve Draw.Bu iki fonksiyonda oyunumuz sonlanana kadar devamlı olarak belirli görevleri yerine getirmekle sorumlu.Update fonksiyonu sürekli olarak bizim belirlediğimiz koşulları denetleyebileceğimiz,kullanıcıdan herhangi bir girdi alabileceğimiz kontrol mekanizmalarının çalıştığı,ses parçalarının yürütüldüğü,oyun içi AI ve çarpışma tespiti amaçlı kontroller yapabileceğimiz bir fonksiyondur.Draw fonksiyonu da sürekli olarak karşımıza hazır olarak gelen oyun penceremiz üzerinde çizim yapar.Ortalama olarak 60 FPS(9) civarlarında görüntü sağlayacak şekilde çalışır diyebiliriz.Tabi bu konuda yazılımın ihtiyaçlarını eldeki donanımın karşılama oranı ile bizim yazılımda özel bir şeyler deniyor olmamız gibi faktörleri göz önünde bulundurmamızda fayda var.
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// Provides a snapshot of timing values.
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// This is called when the game should draw itself.
/// Provides a snapshot of timing values.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
}
Bundan sonra ki yazılarımda XNA sınıflarını incelemeyi ve özel örneklerle artık elle tutulur projeler üzerine yoğunlaşmayı planlıyorum.Takip etmeye devam edin ve sağlıcakla kalın.
(1) Burada kullanılan anlamıyla C# ın (adını bizim koyduğumuz) programımıza verdiği ad uzayı(namespace)
(2) XNA ye Giriş-Content Pipeline http://www.mayhemcorporation.com/mayhem/index.php?topic=12
(3) Game Loop-Oyun Döngüsü : Başla -Yükle-Güncelle-Bitir
(4) AI : Artificial Intelligence ,Yapay Zeka (Örnek olarak oyunda düşmanların hareketleri)
(5) Collision Detection(Çarpışma Tanımlama):Oyun programlamada çok önemli bir işlem olup en basit olarak; normal dünyada uyurken yatağın içinden geçip gitmemiz için yaratanın yazdığı, iki cismin birbirine teması ve etkileşimleriyle ilgili belirlediği kuralları bilgisayar oyunlarında bir nevi tekrar tanımlanma işlemidir
(6) Hak,Can : Mario gibi oyunlardan dilimize dolaşmış bir kavram olup, Birup (1 UP) aldım diyenleri gördüğüm olmadı değil.Bunun için asla onlara kızmam,çünkü hepimizin kardeş olduğu bir dünya burası ve hepimizin canı var :)
(7) Yapıcı Fonksiyon(Constructor) : Nesneye yönelik programlamada bir nesne oluştuğunda çalışan ilk fonksiyon olup bellekte yer ayırma ve eğer istenilirse başlangıç olarak ayarlamalarını yapma (Asker sınıfından türemiş nesnelerin ilk olarak ellerinde mızrak olsun)gibi işlemleri gerçekleştirir