Hoşgeldiniz: OyunYapimi.org
 
Ara
Konular
  Üye Olun!    
Ana Menü
 Ana Sayfa
 Anketler
 Dosyalar
 Dökümanlar
 Forum
 Haber Arşivi
 WWW Linkleri
 Üye Listesi

Forumlar
Forumlarda Arama
 
[ Ara ]
Son yazilanlar

free ebooks - 2004-05-16 14:47 free ebooks...
oyun yazmak için - 2004-05-15 11:13 oyun yazmak için...
Sinus dalgası - 2004-05-14 19:21 Sinus dalgası...
Demosu yakında... - 2004-05-06 15:11 Demosu yakında......
Depth Test - 2004-05-03 20:55 Depth Test...
forum mesajlarini duzenlemek - 2004-05-03 19:34 forum mesajlarini ...
Başka Programlara Erişmek - 2004-05-03 17:44 Başka Programlara ...
Güzel bir e-book bağlantısı.. - 2004-05-03 16:06 Güzel bir e-book b...
Okyanus Dalgasi - 2004-05-03 16:00 Okyanus Dalgasi...
3d Shoot em up - 2004-05-03 15:57 3d Shoot em up...
Esnek Güç - 2004-05-03 13:32 Esnek Güç...
UltimateGameProgramming.com - 2004-05-03 12:29 UltimateGameProgra...
Function Pointer Nedir ne ise yarar - 2004-05-03 01:35 Function Pointer N...


Konu Disi


LAMER - 2004-05-10 01:58 LAMER...
anasafa yok forum var - 2004-05-08 16:01 anasafa yok forum ...
Anasayfa Kapali  Fakat.. - 2004-05-06 15:05 Anasayfa Kapali F...
Texture Arşivi - 2004-05-03 01:39 Texture Arşivi...
Yeni Kitap: Elektronik Hobi - 2004-05-03 00:29 Yeni Kitap: Elektr...
3DTURK - 2004-05-02 23:27 3DTURK...
Online Oyun - 2004-05-02 19:27 Online Oyun...


Splatt Forum

Oyun Yapımı - 2 (Temel Görsel Sınıflara Giriş)

(2280 kelime)
(758 okuma)   Yazdırılabilir Sayfa




Oyun Yapımı - 2

1. Ana Sınıfların Oluşturulması:

Projeyi gerçekleştirirken nesneye yönelik bir yaklaşım izleyeceğimizi söylemiştik. İsterseniz ilk olarak bir 3 boyutlu uygulamada en temel nesnelerden birini tasarlayarak işe başlayalım. Oyunumuzun türü ne olursa olsun mutlaka ekranda hareket eden bazı cisimler çizmek, bunların konumlarını zaman içinde değiştirmek zorunda kalacağız. 3 boyutlu dünyamız içinde yer alacak cisimlerin ortak özellikleri ne olacaktır diye düşünecek olursak, ilk akla gelen özellik şüphesiz konum bilgisidir. Her cismin 3 koordinat ile ifade edilen (x, y, z) bir konumu olmalıdır. Bazı cisimler sabit olmakla beraber birçok cisimde hareket etme özelliğine sahip olacaktır. Dolayısı ile bir cismi hareket ettiren yani konumunu değiştiren yordamlara da ihtiyacımız var. Ve tabi ki her cismin birde görüntüsü olmalı. Yani cisimler için bir adet de çizim yordamı tasarlamamız gerekmekte.

Ben yukarıda saydığım işlev ve özellikleri destekleyen bir sınıf oluşturmayı uygun görüyorum. Bu sınıf kendisinden nesne türetilemeyen, yani 'abstract' bir sınıf olacak ve ekranda çizilebilen nesneler bu sınıftan türeme yolu ile oluşturulacaklar. Daha sonra ihtiyaç duydukça bu sınıfa eklemeler yapabileceğiz. Bu arada, projemizi yaparken artık standartlaşmış bir kütük yapısını uygulayacağız. Bu yapıya göre; her sınıf tanımı 'sınıf_ismi.h' isimli kütüklerde, gerçekleştirim yordamları ise 'sınıf_ismi.cpp' isimli kütüklerde bulunacaklar. Kimi zaman sınıflar kullanmak yerine 'struct' olarak bazı tanımlamalarda bulunacağız. Bu tanımlamaları da 'types.h' isimli kütükte toplayacağız. Aynı zamanda bu kütükte OpenGL ve SDL ile ilgili genel 'include' lar da bulunacak. Böylelikle artık her ihtiyacımız olduğunda sadece 'types.h' ı include etmemiz yeterli olacak.

Bahsettiğimiz ana 3 boyutlu cisim sınıfımıza 'Entity' adını verelim. Aşağıda bu sınıfın tanımı, gerçekleştirim yordamları ve types.h isimli kütükte bulunan 'Vec3d' isimli yapı kaynak kod olarak verilmiştir. Vec3d pozisyon bilgisi tutmakta kullanacağımız bir yapı. Bu yapıyı kullanarak bir seferde x,y,z koordinatlarının hepsini birden taşıyabileceğiz. Sizde aşağıdaki kodda yer alan sınıfları, kendi kütüklerinizi proje içine dahil edip kodu uygun kütüklere kopyalayarak oluşturunuz.

// --- Types.h ------------------------------

#ifndef __TYPES__H__
#define __TYPES__H__

struct Vec3d {
   float x,y,z;
};

#endif

// --- Entity.h ------------------------------

#ifndef __ENTITY_H__
#define __ENTITY_H__

#include "types.h"

class Entity {

public:

   Entity()  {};
   ~Entity() {};

   void  move(const Vec3d *delta);
   void  setPosition(float x,float y,float z);
   Vec3d getPosition() const;

   // Bu sınıftan türeyen sınıflar içerisinde render() yordamı
   // içeriği oluşturulmak sureti ile cisimlerin çizim işlemi
   // gerçekleştirilecek. Aşağıdaki tanım aynı zamanda Entity
   // sınıfından direk olarak bir nesne türetilmesini de engellemiş
   // oluyor.
   virtual void render() = 0;

protected:

   Vec3d position;


};

#endif

// --- Entity.cpp ------------------------------

#include "Entity.h"

// Bu yordam ile cismi delta vektörü doğrultusunda hareket ettiriyoruz
// Başka bir deyişle delta vektörü ile belirtilen değerler doğrultusunda
// cisim x,y, ve z eksenlerinde öteleniyor.
void Entity :: move(const Vec3d *delta) {

   position.x += delta->x;
   position.y += delta->y;
   position.z += delta->z;

}

// Bu yordam ile cismin konumunu belirliyoruz.
void Entity :: setPosition(float x,float y,float z) {

   position.x += x;
   position.y += y;
   position.z += z;

}

// Bu yordam bize cismin konumunu veriyor.
Vec3d Entity :: getPosition() const {

   return position;

}

2. İlk Görsel Cisim:

Ana cisim sınıfımızın iskeletini bu şekilde oluşturmuş olduk. İsterseniz şimdi bu sınıftan çizim kabiliyetine sahip ve direk olarak kullanabileceğimiz bir alt cisim sınıfı oluşturalım. Hayal gücümüzü fazla zorlamamıza gerek yok (en azından bu aşamada..). Örnek olarak bir top sınıfı oluşturacağız. Top nesneleri birçok oyunda çeşitli görevlerde karşımıza çıkmakta olan vefakar dostlardır :). Bizim top nesnemizde her iyi top nesnesi gibi yuvarlak, basit ve renkli olacak. Bu top nesnesi aynı zamanda temel Entity sınıfından türediği için bu sınıfın konum özelliğini ve ilgili yordamlarını da içinde kalıtım yolu ile bulunduracak. Aşağıdaki kodları Ball.h ve Ball.cpp kütüklerinin içine yazın.

// --- Ball.h -----------------------------

#ifndef __BALL_H__
#define __BALL_H__

#include "entity.h"

class Ball : public Entity {

public:

   Ball() {};
   ~Ball() {};

   void  setColor(float r,float g,float b);
   Vec3d getColor();

   virtual void render();

protected:

   float r,g,b;

};


#endif

// --- Ball.cpp -----------------------------

#include "ball.h"

// Bu yoram ile topun rengini değiştirebiliyoruz.
void Ball :: setColor(float r,float g,float b) {

   this->r = r;
   this->g = g;
   this->b = b;

}

// Bu yordam bize topun rengini bir Vec3d yapısı olarak geri döndürüyor.
Vec3d Ball :: getColor() {

   Vec3d col = {r,g,b};
   return col;

}

// Bu yordam ile topun çizim işlemini gerçekleştiriyoruz. Önce topun
// rengini aktif OpenGL rengi haline getiriyor, daha sonra ise bir GLUT
// fonksiyonunu kullanarak 1 birim çapında, 20 enine 20 de boyuna çizgi
// kesiti içeren bir içi dolu küre çizdiriyoruz.
void Ball :: render() {

   glPushMAtrix();
   glTranslatef(position.x,position.y,position.z);
   glColor3f(r,g,b);
   glutSolidSphere(1.0f,20.0f,20.0f);
   glPopMatrix();

}

Artık elimizdeki Ball sınıfından çeşitli renklerde toplar elde ederek bunları ekranda görüntüleyebilecek aşamaya geldik. Aşağıdaki yeni main.cpp kodunu yazarak programı derleyip çalıştırın. Rengarenk toplarımızı doyasıya seyredebiliriz :).

// --- Main.cpp -----------------------------

#include "types.h"
#include "Ball.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define BALL_COUNT 5

Ball balls[BALL_COUNT];

void initSDL(int width,int height,int bpp) {

   // Bu yoram SDL kütüphanesini baslatan yordamdir. SDL kütüphanesinin VIDEO
   // ve zamanlama kisimlarini kullanmayi düsündügümüz için buna uygun
   // parametreleri kullandik. Herhangi bir hata durumunda ise SDL_GetError()
   // yordami ile hatanin sebebini ögrenip ekrana (yada stdout.txt kütügüne)
   // yazdiriyor ve programdan çikiyoruz.

   if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
      fprintf(stderr,"SDL baslatiminda hata! %s",SDL_GetError());
      exit(-1);
   }

   // exit() yordami çagirildiginda buna ek olarak SDL_Quit() isimli SDL yordaminin da
   // çagirismasini asagidaki kod ile belirtmis oluyoruz. SDL_Quit() yordami SDL
   // kütüphanesini kapatan yordamdir. Bu sekilde artik program sonunda SDL_Quit()
   // yordamini çagirmak yerine sadece exit() yordami ile bu isin otomatik gerçeklesmesini
   // saglamis olduk.

   atexit(SDL_Quit);

   // Bu yordam ile nihayet genisligini, yüksekligini ve renk çözünürlügünü belirledigimiz
   // bir pencere açiyoruz. SDL_OPENGL  parametresi bu pencereyi OpenGL altindan
   // kullanacagimizi belirtiyor.

   if (SDL_SetVideoMode(width,height,bpp,SDL_OPENGL) == NULL) {
      fprintf(stderr,"SDL ekrani açamadi!");
      exit(-1);
   }

}

void setupOpenGL(int width,int height) {
   
   // poligonlarin cizim sirasinda oncelik kontrolu icin Z Buffer
   // teknigini kullan.
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
   
   // poligonlarin icini doldurmada renk gecislerini yumusak yap
   glShadeModel(GL_SMOOTH);
   
   // arka fon rengi siyah olsun
   glClearColor(0,0,0,0);

   // goruntuyu olusturacagimiz alani belirt.
   glViewport(0,0,width,height);

   
   // opengl de goruntu olusturulacakken kullanilacak sanal kameranin
   // lens ayarlarini gerceklestir (bakis acisi ve menzil ayarlari...)
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45,(float)width/(float)height,0.1f,4000.0f);
   glMatrixMode(GL_MODELVIEW);

}

void renderScene() {

   // Onceki seferde cizilenleri siliyoruz. Ayni zamanda Z Buffer
   // algoritmasinin duzgun islemesi icin Z Buffer daki onceki seferden
   // kalma bilgilerde sifirlaniyor.
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   // Kamera poziyonunu sıfırlıyoruz.
   glLoadIdentity();

   // Kameramızı biraz geri alalımki dünyadaki çizimleri gözlemleyelim..
   // (Yani cisimler kameranın arkasında kalmasınlar...)
   glTranslatef(0.0f,0.0f,-30.0f);
   
   // Tüm topları tek tek çiziyoruz.
   for (int i=0;i<BALL_COUNT;++i) {
      balls[i].render();
   }
      
   // Bellekte olusturulan cizim pencere icine aktariliyor. Bu sekilde
   // goruntuyu ekranda gorebiliyoruz.

   SDL_GL_SwapBuffers();

}

int main(int argc,char *argv[]) {

   // Ana donguden cikis icin kullandigimiz degiskenimiz.

   bool quit = false;

   // SDL kütüphanesini başlatıp, ekranda bir pencere açiyoruz.
   
   initSDL(640,480,16);
   setupOpenGL(640,480);

   // Her top nesnesi için rastgele koordinat ve renk değerleri
   // belirliyoruz.
   srand(time(NULL));
   for (int i=0;i<BALL_COUNT;++i) {
      balls[i].setPosition(0.1f * (rand()%100) - 5.0f,
                           0.1f * (rand()%100) - 5.0f,
                           0.1f * (rand()%100) - 5.0f);
      balls[i].setColor(0.01f * (rand()%100),0.01f * (rand()%100),0.01f * (rand()%100));
   }
      
   while (!quit) {

      renderScene();
      
      // SDL de giris/cikis islemleri event ler vasitasi ile yurutulur.
      // Burada bir event nesnesi tanimi yapiyoruz.
      
      SDL_Event event;

      // SDL_PollEvent() fonksiyonu ile hazirda bekleyen birsonraki event i
      // event yapisi icerisinde elde ediyoruz.

      while (SDL_PollEvent(&event)) {

         // event.type bize event in turunu belirtir. SDL_KEYDOWN tipi tusa
         // basilma durumunda olusur.
         
         switch (event.type) {
         
            case SDL_KEYDOWN:
               
               // event.key.keysym.sym degiskeni basilan tusun kodunu icermektedir.
               // SDL icerisinde tus kodlari SDLK_* biciminde tanimlanmistir. Kod
               // SDLK_ESCAPE ise kontrol degiskenimizi gunleyerek donguden cikma isini
               // gerceklestiriyoruz.
               
               switch (event.key.keysym.sym) {
                  case SDLK_ESCAPE:
                     quit = true;
                     break;
               }
               break;

            // Pencerenin kapatma tusuna basilmasi ise yine bir event uretir.
            // Bu event in tipi SDL_QUIT dir. Bu durumda da yine cikis islemini
            // yapiyoruz.

            case SDL_QUIT:
               quit = true;

         }
      }

   }
   
    return 0;
}

Bir sonraki dersimizde cisimlerin klavyeden alınan girdiler sonucu hareketlendirilmesi konusunu işleyecek ve yeni görsel cisim sınıfları oluşturmaya devam edeceğiz. Kendinize iyi bakın.
Deniz Aydınoğlu :: 2002



  

[ Geri Dön: Oyun Yapımı (Genel) | Dökümanlar İndeksi ]





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.