Oyun Programlamaya Giriş 1

Etrafta uçuşan bombalar, vızır vızır geçen mermiler arasında yol bulmaya çalışmak, otobanda ters yönde son sürat bir Ferrari kullanmak, sahalara inip inanılmaz goller atmak yada sakin bir göl kıyısında elde olta balık peşinde koşmak. Bu söylediklerim çok mu zor? Peki bombardıman altında ters yönde bir Ferrari'yle son sürat karşı kaleye doğru top sürmek? Daha mı uçuk? Bence sadece hayal gücüyle sınırlı bir dünyanın içinde yapılabilinecek ufak bir iki numaradan ibaret.

1952 de A.S. Douglas ilk grafik tabanlı TicTacToe'yu yazıldığında sanırım bu kadarını hayal etmemişlerdi. Şimdi ise etrafımız grafik canavarı oyunlarla kaplanmış durumda.Half-Life, Suffering, Doom, F.E.A.R. vs. oynamak için hayal gücü dahili içinde olmayan güçlerde PClere ihtiyaç duymaya başladık. Peki nasıl oluyorda bu 1 ler 0 lar eli kanlı dev yaratıklar olup geceleri peşimizde kabus gibi dolanabiliyorlar? Bu benim de inanılmaz merak ettiğim ve bir şekilde cevap alabilmek için çırpındığım bir soruydu. Ben kim miyim? Ben naçizane bir üniversiteden mezun, programlama ve oyun tutkunu, bu yüzden de oyun programlamaya merak sarmış bir Türk genciyim. Nelerle mi ilgileniyorum? Hafif C, şöle böle C++, Java gibi bişe, biraz ARM7 assembler, azıcık da PHP... Birazda DirectX ve OpenGL le ilgim alakam var. Ne bir DirectX ne de bir OpenGL ustasıyım fakat, şimdiye kadar internette oyun programlama ile ilgili Türkçe adam gibi hiçbir kaynağa rastlayamadım. Bunun sonucunda bende böyle birşeyler yapmak istedim, yapabildiğim kadarıyla.

Burada oyun programlama, oyun yapısı, oyun motorları, diller, oyun türleri hakkında kısa yazılar yazmaya çalışacağım. Öncelikle yazdıklarımı oyun programlama hakkında birşey bilmeyenler için anlaşılır ama programlama bilmeyen biri için anlaşılamayabilir olacağını baştan söylemek isterim. Sizlerle beraber bende birçok yeni şeyler öğrenirken bunları Türkçe bir kaynaktan duyurmak istediğim için burda olduğumu tekrar hatırlatmak isterim... İsterseniz yavaş yavaş bir giriş yapalım artık.

Bu yazıda basit olarak içeriden bakınca oyunun ne olduğu ve yapısı hakkında birşeylerle başlayacağız. Oyunlar gerçekten karmaşık ve kompleks birer yazılımlardır. Hatta bazı kitaplara ve internet sitelerine göre en zor yazılan programlardır. Oyunlar tek satırlı, etki-tetiklemeli (event-driven) veya ardışıl mantılkı (sequential logic) programlardan daha çok, gerçek zamanlı ve simülasyon programlarına daha çok benzer. Oyun basit olarak arkada bir mantık çalıtıran ve ekranda yapılan işlemlerin sonuçlarını 30-60 fps ile yansıtan sürekli bir döngüen oluşur. Bu döngüye oyun döngüsü (game loop) denilmektedir. Aslında ekranda görülen herşey bu oyun döndüsü içinde oluşmakta. Yapay zeka, ekran düzenlemeleri, hesaplamalar tamamen bu döngü içinde yapılmakta. Bu yüzden yazılan algoritmaların performansı oyunun perormansını birebir etkilemekte. Oyun döngüsünün yapısına kısaca bir bakalım:

Basit olarak oyun döngüsü
Şekil 1. Basit Oyun Döngüsü Yapısı

Şimdide yukarıdaki grafiği biraz inceleyelim.


  1. Değerleri Sıfırlama ( Initialization ):
    Burada standart herhangi bir programı yazarken yapacağınız işlemler yapılır. Mesela Hafıza ayırma, diskten bilgi yükleme, ilk değerleri yerleştirme vs. vs.


  2. Oyun Döngüsüne Gir:
    Burada kod asıl döngüye, oyun döngüsüne girer. Burada oyundan çıkana kadar oyunun içindeki herşey gerçekleşir.


  3. Oyuncudan Girdi Al:
    Burada oyunu oynayan kimseden girdi alımı, bu girdinin işlenmesi gibi oyun-oyuncu interaktif ilişkisini sağlayacak işlemler gerçekleşir.


  4. Yapay Zeka ve Oyun Mantığını Uygula:
    Burası oyunun asıl bölümlerinden biri hatta en önemlisidir. Oyununuz içindeki oyuncu dışında kontrol edilen karakter ve ortamların yapay zeka algoritmaları, oyunun kuralları ve mantıkları burada işin içine girer. Ve burada genel oyun mantığı çalıştırılmış olur. Bundan sonra bir sonraki görüntünün işlenmesi işlemini geçilir.

  5. Bir Sonraki Ekranı Çözümle:
    Burada daha önce aldığımız kullanıcı girdileri, çalıştırdığımız yapay zeka ve oyun mantığı algoritmalarının sonuçlarını kullanarak ekranda o andan bir sonraki ekran görüntüsünün işlenmesi işlemi gerçekleştirilir. Bu oluşan görüntü yapıldığı anda değil bittikten sonra o an ekranda bulunan görüntüden hemen sonra ekrana gelir. Bu şekilde peşpeşe gelen ekran görüntüleri oyuncu için animasyon ilüzyonu yaratır.


  6. Görüntüyü Senkronize Et:
    Bazı bilgisayarlar oyunun kompleksitesine göre daha yavaş veya daha hızlı çalışabilirler. Ekranda 1000 tane objenin bulunmasıyla 10 tane obje bulunması arasında performans farkı olacaktır. Bu da oyun içinde saniyedeki görüntü sayısının (FPS) değişmesine sebep olur, ve bu bir oyun için çok kabul edilebilir birşey değildir. Bu yüzden oyunun fps’sinin programlayan kimse tarafından düzenlenmesi ve belli seviyelerde tutulması sağlanmalıdır. Bir oyunda minimum kabul edilebilir fps değeri 30fps’dir, 60 fps ise idealdir. 60fps üzerinde bir performansa sahip olmanın pek faydası yoktur çünkü insan beyninin saniyede 60 görüntüden yukarısını işlemekle ilgili problemleri vadır.


  7. Döngü:
    Bu bölüm çok kolaydır, sadece döngünün en başına dönmek yeterlidir.


  8. Kapat:
    Burası oyunun sonu demektir. Oyuncu ana oyun döngüsünden çıkmış ve işletim sistemine geri dönmek için oyuna gerekli komutu vermiştir. Fakat oyunu terketmeden önce yapılması gereken bazı işler vardır. Oyunda alınmış kaynakların bırakılması, hafızanın temizlenmesi, gerekli oyun değerlerinin saklanması ve sistemin temizlenmesi bu işlerin başında gelmektedir.


Yukarıda yazdıklarımızı isterseniz bir de algoritmik olarak ifade etmeye çalışalım.


// oyun dongusu durumlarinin tanimlamalari
#define GAME_INIT // oyun ici degerler yaratiliyor
#define GAME_MENU // oyun menu modunda,
#define GAME_START // oyun basliyor
#define GAME_RUN // oyun calisiyor
#define GAME_RESTART // oyun yeniden basliyor
#define GAME_EXIT // oyundan cikis
// oyun globalleri
int game_state = GAME_INIT; // oyun ici degeleri yaratma pozisyonunda basla
int error = 0; // isletim sistemine hatalari dondurmek icin kullanilacak
void main()
{
while(true)
{
// oyun dongusunun uygulamasi
switch(game_state)
{
case GAME_INIT:
{
// tum kaynaklari ve hafiza alanlarini yarat
init();
// menu moduna gec
game_state = GAME_MENU;
} break;
case GAME_MENU:
{
// ana menu fonksyonunu cagir ve oyun durumunu degistirmesine izin ver
game_state = GAME_MENU;
} break;
case GAME_START:
{
// burada oyun baslamadan onceki son hazirliklar yapilir
Setup_For_Run();
// baslama moduna gec
game_state = GAME_RUN;
} break;
case GAME_RUN:
{
// burada oyunun tum mantigi bulunnmakta.
// goruntuyu temizle
Clear();
// girdi al
Get_Input();
// oyun mantigi ve yapay zekayi uygula
Do_Logic();
// bir sonraki ekranin hazirla
Render_Frame();
// goruntuyu 30fps+ seviyesinde tutmak icin ayarla
Wait();
// bu durumda oyunun durumu sadece oyuncu etkisiyle yada
// oyunu kazanip kaybetmesine göre degisebilir.
} break;
case GAME_RESTART:
{
// Bu bolum herseyin temizlendigi ve yeniden yaratildigi alandir.
// Oyun yeniden baslamadan once degerleri duzelenler
Fixup();
// geri ana menuye don
game_state = MENU;
} break;
case GAME_EXIT:
{
// bu bolumde tum kaynaklari sil yada bosalt
Release_And_Clenaup();
error = 0;
}
default: break;
} // switch bitir
} // donguyu bitir.
return (error);
}


Yukarıdaki oyun döngüsü mantığına bakılırsa, aslında oyun döngüsünün çok basit bir yapıya sahip olduğunu gösteriyor. Bu yukarıdaki döngü sadece bir while ve bir switch den ibaret bir algoritmaya sahip.

Bugün çok basit olarak bir oyunun yapısı nedir, nasıl yapılır hakkında bir fikre sahip olmaya çalıştık. Bundan sonraki yazılarda biraz daha koda girmeye başlayacağız. Bir daha ki sefere görüşünceye kadar hoşçakalın.


randomHero tarafından 22.04.2005 tarihinde yazılmıştır.

Labels: , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home