Ana Menü
· Ana Sayfa
· Dosyalar
· Dökümanlar
· Forum
· Günün Resmi
· Haber Arşivi
· WWW Linkleri
· Üye Listesi

     Forumlar

 strncpy ve strncpy_s
 Konu adi : Borland c++ Builder ile Amiral Batti
 Rady10 - YerliOyun
 Kabusta Kaybolmak
 Konsol da programı bekletmek
 Oyun programlama icin hangi programlama dilli ?
 flash! şanlıurfa bilgisayar oyununda(no rapid)
 Sevgilim Olur musun?
 Directx'e başlamak isteyenler bi bakın
 PSP programlama
 Flash tan php
 Bilgisyr oyunu yapmam için üniverstde hangi bölüme girmeliym
 www.arshiv.gen.ms
 Cimg.h ilgilenenler icin
 müttefik oyunu

Konu Disi
 Emraah
 Yeni sitemiz açıldı
 Kalp krizi durumunda ne yapılmalı?
 Oyun sektöründe hangi görevde çalışmak isterdiniz?
 Takım arkadaşı sorunu
 msn de renklı nıck
 pc hata veriyor ! YARDIM!!
 Gülmek isteyenler Buraya
 İnanılmaz hl 2 modu görüntüsü
 Computer Languages History

[ Forumlara Git ]


SDL ile Pong Yapalım

(2387 kelime)
(585 okuma)   Yazdırılabilir Sayfa




Merhaba, bu dersimizde basit bir pong oyunu yapacağız. SDL ile ilgili temel bilginizin olduğunu düşünerek derse başlıyoruz. Öncelikle neler gerektiğine bir bakalım ve global bazı tanımlar yapalım.Yazacağımız pong oyununu oynayın ve önce ne yapacağımıza bir bakın. Bu sayede eminim ders daha anlaşılır gelecektir.

Programı indirdiyseniz gördüğünüz üzere 2 raket ve bir top var, raketler sürekli birbiri ile aynı hareketi yapıyor. Oyun diğer bazı pong lardan farklı olarak tek kişilik. Nedeni ise hem size oyunda geliştirecek bir alan bırakmak hem de dersi daha anlaşılır hale getirmek.

Kütüphanelerimizi ekledikten ve linker ayarlarını yaptıktan sonra, klasik SDL tanımları ile başlayalım :

SDL_Surface *ekran; //klasik ekran yüzeyimiz
SDL_Surface *raket; //raket
SDL_Surface *top; //top

Sırada gerekli olacak bazı değişken tanımları var. Global değişken kullanmaktan sakının, ancak bu giriş dersi olduğu ve çok da büyük bir program olmayacağı için buna gerek yok. İşte bazı değişkenlerimiz, bunlar şu an için havada şeyler ancak ilerde kullanırken anlatacağım.

#define RAKETBOYU 100
#define RAKETENI 20
#define RAKETHIZI 300
#define TOPBOYU 32
#define TOPHIZI 100

#define YUKSEKLIK 300 //pencere boyutları
#define GENISLIK 500

int raket_poz; //iki raket de aynı pozisyonda olacak
float top_x = GENISLIK / 2, top_y = YUKSEKLIK / 2; //topun pozisyonu

int top_hizi_x = TOPHIZI; //top hızları, bunları puana/zamana göre değişken yaparak oyuna renk katabilirsiniz
int top_hizi_y = TOPHIZI;

int skor = 0; //skor değişkenimiz

float time;

İstenilen raket, top ve ekran boyutlarının/hızlarının ayarlanılabilmesi için bu değerleri ön işlemci tanımı ile bildirdim. YUKSEKLIK veya GENISLIK gibi değerleri değiştirmeniz çarpışma işlemlerine etki etmeyecek çünkü bu değerler üzerinden işlem yapacağız. "time" değişkenimiz ise FPS den bağımsız hareket edebilmemizi sağlayacak. Küçük oyunlarda bu çok önemli, ya fps yi kitlemeli, ya da fps den bağımsız işlem yapmalısınız. Aksi halde oyun her bilgisayarda farklı bir hal alacaktır. Klasik resim çizme fonksiyonumuzu da unutmayalım :

//x,y konumuna resim çizer
void ResimCiz(SDL_Surface *resim, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(resim, NULL, ekran, &dest);
}

Sıra geldi esas fonksiyona yani Render(). Bu fonksiyon her ekran yenileceği sırada çağrılacak ve ekranı silip üstüne bizim resimleri, yani topu ve raketleri çizecek. Eğer ekranı sildirmezsek ne olacağını önceki derslerde söylemiştim.


void Render()
{
SDL_FillRect(ekran,NULL,0x000000);
ResimCiz(top, int(top_x), int(top_y));
ResimCiz(raket, 0, int(raket_poz));
ResimCiz(raket, GENISLIK - RAKETENI, int(raket_poz));

//top için saydamlık
SDL_SetColorKey(top, SDL_SRCCOLORKEY, SDL_MapRGB(top->format, 255, 0, 255));

//raketin saha dışına çıkmasını önleyelim
if(raket_poz < 0) {raket_poz = 0;}
if(raket_poz > YUKSEKLIK - RAKETBOYU) { raket_poz = YUKSEKLIK - RAKETBOYU;}

//topun yeni pozisyonunu belirleyelim
top_x += top_hizi_x * time;
top_y += top_hizi_y * time;

Bu kısma kadar anlaşılmayacak bir yer görmüyorum. Kısaca açıklamak gerekirse, Resimlerimize uygun pozisyonlar bulduk ve çizdik, daha sonra top için saydam renk belirledik ve raketin ekran dışına çıkmasını önledik. Sonrasında ise topumuzu yeni pozisyonunua atadık. Top yeni pozisyonlarında bir sonraki frame de çizilecek. Bir de topun saha kenarlarına çıkmasını engelleyelim. Top saha kenarlarına çarptığında, yani yukarı veya aşağı çarptığında(çarpma işlemi pozisyon kontrolü ile hesaplanır) top_hizi_y değerini eksi ile çarpıyoruz ve en basit sekme efektini elde etmiş oluyoruz.

//topun saha kenarlarına çarpması
if(top_y < 0) {top_y = 0; top_hizi_y = -top_hizi_y; }
if(top_y > YUKSEKLIK - TOPBOYU) {top_y = YUKSEKLIK - TOPBOYU; top_hizi_y = -top_hizi_y; }

Ben çarpışma hesabı için ayrıntılı bir sisteme gerek görmedim. Pek çok değişken belli olduğu için karşılaştırmalar ile topun rakete değip değmediğini anlayabiliriz. Yazacağımız sistem oldukça basit, tabii bu basitliği nedeniyle bazı eksileri de var. Sonuç olarak bu dersin kolay olması için çok fazla bu konulara değinmeyeceğim. Eğer uygulamayı geliştirecek olan olursa çarpışma sisteminde bazı yerlere (- int(TOPBOYU/2)) gibi ifadelerin yazılması gerektiğini yani hesapların sol üst köşeye değil, topun en ucuna göre yapılması gerektiğini görecektir. İşte çarpışma için kontrol kodları.

//topun raketlere çarpmasını kontrol ediyoruz
//sol rakete çarpabilir
if(top_x < RAKETENI)
{
if (top_y > raket_poz && top_y < raket_poz + RAKETBOYU) //yakaladık
{
top_x = RAKETENI;
top_hizi_x = -top_hizi_x;
skor += 3;
SkorYenile();
}
else //kaçırdık
gol();
}

//sağ rakete çarpabilir
if(top_x > GENISLIK - (TOPBOYU + RAKETENI))
{
if (top_y > raket_poz - TOPBOYU && top_y < raket_poz + RAKETBOYU)
{
top_x = GENISLIK - (TOPBOYU + RAKETENI);
top_hizi_x = -top_hizi_x;
skor += 3;
SkorYenile();
}
else //kaçırdık
gol();
}

SDL_Flip(ekran);
}

Bu kodlarda yapılanlar topun sol üst köşesinin raketin x pozisyonu ile raketin sonunu belirten raket_x + RAKETBOYU değerleri arasında olmasını kontrol etmek. Eğer bu değerler arasında ise top rakete değmiştir, değilse gol olmuştur. Bulduğum en basit sistem bu. :-) tabii isteyenler bounding ile, isteyenler per-pixel hesaplar ile de çarpışma kontrolü yapabilir. Ben gerek görmedim. Çarpışmanın tepkisi olarak yapılan işlem ise top_hizi_x değişkenini eksi ile çarpmak, yani hareketi x ekseninde ters çevirmek.

Render fonksiyonu içinde bazı fonksiyonlar kullandık bunlar isimlerinden anlaşılabilecekleri gibi, ekrandaki(üst bardaki) skor yazısını yenileme fonksiyonu ve gol(); fonksiyonu. Bunların tanımları şöyle:

void SkorYenile()
{
static char str[256];
sprintf(str,"SKORUNUZ : %d",skor);
SDL_WM_SetCaption(str,NULL);
}

//top raketi geçmişse yeni pozisyona getirir ve 10 puan azaltır
void gol()
{
skor -= 10;
top_x = GENISLIK/2;
top_y = YUKSEKLIK/2;

SkorYenile();
}


Bu şekilde skorumuzu da en basit yoldan görmüş oluyoruz. Ancak oyun henüz bitmedi, gerçi bu kısımdan sonrasını önceki derslere bakarak da yapabilirsiniz, yapılacak işlemler klasik sdl ayarlamaları:
int main(int argc, char *argv[])
{
Uint8* BasilanTus;

if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
{
printf("SDL baslatilamadi: %sn", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);

ekran = SDL_SetVideoMode(GENISLIK,YUKSEKLIK,32,SDL_HWSURFACE|SDL_DOUBLEBUF);

if ( ekran == NULL )
{
printf("Ekran oluşturulamadı: %sn", SDL_GetError());
exit(1);
}

Resim yükleme, skor yenileme gibi oyun başlar başlamaz çalışan fonksiyonlar:

raket = SDL_LoadBMP("raket.bmp");
top = SDL_LoadBMP("top.bmp");

SkorYenile();

ve tabii ana döngü:

bool bitti = false;

while(bitti == 0) //game loop
{
SDL_Event olay;

while ( SDL_PollEvent(&olay) )
{
if ( olay.type == SDL_QUIT ) { bitti = true; }

if ( olay.type == SDL_KEYDOWN )
{
if ( olay.key.keysym.sym == SDLK_ESCAPE ) { bitti = true; }
}
}


static float frameTime = 0.0f; // This stores the last frame's time
float currentTime = SDL_GetTicks() * 0.001f;

time = currentTime - frameTime;
frameTime = currentTime;


BasilanTus = SDL_GetKeyState(NULL); //basılan tuşu algılar
if ( BasilanTus[SDLK_UP] ) { raket_poz -= RAKETHIZI * time; } //yön tuşları ile hareket
if ( BasilanTus[SDLK_DOWN] ) { raket_poz += RAKETHIZI * time; }

Render(); //ekranı çiziyoruz
}
//program bitirildiyse
return 0;
}

İşte bu kadar en basit şekli ile bir pong yaptık. İsteyenler 2 kişi modu, daha güzel çarpışma sistemi, sesler, font sınıfı... gibi eklentiler ile oyunu daha güzel bir hale getirebilir. Eklenti yapmayı deneyin, bu şekilde daha iyi öğreneceğinizden kuşkunuz olmasın.

[ VC++6.0 proje dosyalarını ve programın çalıştırılabilir halini indirmek için tıklayın - (11Kb) ]

Görüşmek üzere
+-+-+-+-
STR
Stroma :: 2005 :: www.oyunyapimi.org
  

[ Geri Dön: Oyun Yapımı (Genel) | Bölümler İndeksi ]




Web site powered by PHP-Nuke
Web site engine\'s code is Copyright © 2002 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Sayfa Üretimi: 0.032 Saniye