Jump to page: 1 2 3
Thread overview
MVC -> D <- SDL'nin Buluştuğu Nokta
Aug 13, 2012
Salih Dinçer
Aug 13, 2012
Salih Dinçer
Aug 13, 2012
erdem
Aug 13, 2012
Salih Dinçer
Aug 13, 2012
erdem
Aug 13, 2012
Salih Dinçer
Aug 13, 2012
erdem
Aug 19, 2012
Salih Dinçer
Aug 19, 2012
erdem
Aug 19, 2012
Salih Dinçer
Aug 20, 2012
Salih Dinçer
Aug 20, 2012
Salih Dinçer
Aug 20, 2012
Salih Dinçer
Aug 20, 2012
Salih Dinçer
August 13, 2012

Merhaba,

Bu hafta bir MVC olayını öğrenelim, ne dersiniz? Lütfen herkes katılım sağlasın; fikir katkısı olsa bile. Böylece hepimiz daha çok şey öğrenip bilginin büyümesine şahit olacağız...:)

Geçen hafta şurada (http://ddili.org/forum/post/7331) değindiğimiz için bir kaç küçük hazırlık yaptım. Bugüne kadar D'de MVC denemesi yapamıyordum. Çünkü SDL'yi tanımamıştım ama şimdi istediğimiz amaç (Model) doğrultusunda çevre birimleri dahil (Control) ederek işlem sonucunu ekrana (View) verebileceğiz. Bunun için aşağıdaki gibi basit bir örnek hazırladım:

import std.math, sdl;

  immutable sahneGenişliği   = 640;
  immutable sahneYüksekliği  = 480;
  immutable çerçeveKalınlığı = 40;
  immutable yuvarlakÇapı     = 21;

int main(){
  scope (exit) { // sahneBitir
     SDL_Quit();
     printf("-YAZILIM HATASIZ SONLANDI-\n");
     printf("Hadi yine iyisin...:)\n");
  }
  // Yuvarlağın konumu
  double nXkonumu = sahneGenişliği /2;
  double nYkonumu = sahneYüksekliği/2;

  // Yuvarlağın ivmesi
  double nXivmesi = 0;
  double nYivmesi = 0;

  // sahneKur
  SDL_Surface* sahne = SDL_SetVideoMode(sahneGenişliği, sahneYüksekliği, 0, 0);
  int beyaz = SDL_MapRGB(sahne.format, 0xff, 0xff, 0xff);
  SDL_Rect rect;// = new SDL_Rect();
  rect.w = cast(ushort)(sahneGenişliği - çerçeveKalınlığı);
  rect.h = cast(ushort)(sahneYüksekliği - çerçeveKalınlığı);
  rect.x = cast(short)(sahne.w-rect.w)/2;
  rect.y = cast(short)(sahne.h-rect.h)/2;
  SDL_FillRect(sahne, &rect, beyaz);
  SDL_UpdateRect(sahne,0,0,sahne.w,sahne.h);

  SDL_Event event;
  bool solTuş, sağTuş, üstTuş, altTuş;
  // sonsuz döngü
  while (true) {
     // nesneÇiz
     if(circleFill(sahne, cast(int)nXkonumu,
                          cast(int)nYkonumu, yuvarlakÇapı, 0)) {
        SDL_Flip(sahne);
     }
     while (SDL_PollEvent(&event)) {
        if(event.type == SDL_KEYDOWN) {
           switch(event.key.keysym.sym) {
              case SDLK_LEFT   : solTuş = true; break;
              case SDLK_RIGHT  : sağTuş = true; break;
              case SDLK_UP     : üstTuş = true; break;
              case SDLK_DOWN   : altTuş = true; break;
              default          : break;
           }
        } else if(event.type == SDL_KEYUP) {
           switch(event.key.keysym.sym) {
              case SDLK_ESCAPE : return 0;
              case SDLK_LEFT   : solTuş = false; break;
              case SDLK_RIGHT  : sağTuş = false; break;
              case SDLK_UP     : üstTuş = false; break;
              case SDLK_DOWN   : altTuş = false; break;
              default          : break;
           }
        } else if(event.type == SDL_QUIT) return 0;
     } // tuş döngüsü
  } // sonsuz döngü
} // program sonu

bool circleFill(SDL_Surface* gScreen, int x, int y, int r, int c) {
 for (int i = 0; i < 2 * r; i++) {
   if ((y - r + i) >= 0 && (y - r + i) < sahneYüksekliği) {
     int len = cast(int)sqrt(cast(float)(r * r - (r - i) * (r - i))) * 2;
     int xofs = x - len / 2;
     if (xofs < 0) {
       len += xofs;
       xofs = 0;
     }
     if (xofs + len >= sahneGenişliği) {
       len -= (xofs + len) - sahneGenişliği;
     }
     int pitch = gScreen.pitch / 4;
     int ofs = (y - r + i) * pitch + xofs;
     for (int j = 0; j < len; j++) {
       (cast(uint*)gScreen.pixels)[ofs + j] = c;
     }
   } // end if()
 } // end for()
 return true;
}

Tabi burada MVC diye bir şey yok ve düz mantıkla çalışıyor. Yani yuvarlak çizme işlevini (circleFill) saymazsak her şey iç içe girmiş. Amacımız ise ekran ortasındaki topu, yön tuşlarını kullanarak duvara çarptırmak ve aksetmesini gözlemlemek. Gerçi yukarıdaki kod bunu yapmıyor ama hele bir MVC yapımızı oluşturalım devam edeceğiz.

Bu arada Windows kullanıcıları çok şanslılar! DMD hariç bir şey kurmalarına gerek yok. Sadece derlerken şuradaki sembol dosyası (https://github.com/erdemoncel/oyun/blob/master/lib/SDL.lib)na, çalıştırırken ise şu iki dosyaya ihtiyaçları var:

Başarılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Teşekkürler hocam, işte bu da bir katkı! Öyle ya, tarih boyu insanoğlu sürekli hata yaptı...:)

Örneğin bir yanlış daha, başlığı "...Buluştuğu Nokta" şeklinde bitirmem gerekirken yanlış yazmışım...

Dosya uzantı konusunda haklısın çünkü LIB, library yani kütüphanenin kısaltılmış. Ama zannedersem bunlar Common Object File Format (COFF) dosyası. Linker ile MS'un kütüphanesine (DLL: dynamic-link library) bağlanıyor. Hep bunlar kafa karıştırıcı ki bir gün D'nin kütüphane olayı ile bir Ders Arası yapalım mı? Bunu da öğrenmeliyiz!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Alıntı (Salih Dinçer):

>

Ama zannedersem bunlar Common Object File Format (COFF) dosyası.

Salihcim bu mesajda bu konuyu biraz anlatmıştım. Yalnız orada ufak bir yazım hatası yapmışım. Microsoft Visual Studio ile gelen derleyici COFF kullanıyor.

http://ddili.org/forum/post/6643

Daha ayrıntılı olarak senin de paylaştığın bu makalede anlatılıyor.

http://www.gamedev.net/blog/1140/entry-2254003-binding-d-to-c/

implib aracıyla var olan DLL dosyasından lib dosyası oluşturabilirsin. Örneğin

'implib -a inpout32.lib inpout32.dll'

şeklinde ya da COFF biçiminden OMF biçimine çevirebilirsin. Bunun için de Digitalmars'ın 'coffimplib' aracını kullanabilirsin ancak bu ücretsiz değil. Borland'ın ücretsiz 'coff2omf 'aracını da kullanabilirsin. Ya da kaynak kodu Borland derleyicileri ile derleyebilirsin. Bundan da şu adreste bahsetmiştim:

http://stackoverflow.com/questions/11421835/correct-way-of-using-a-windows-lib-in-d

Alıntı (acehreli):

>

Özellikle şu yanıtına bakılırsa OMF'ye olan eski bağımlılık ortadan kalkıyormuş:

http://forum.dlang.org/thread/k054e9$1si6$1@digitalmars.com?page=5#post-k0bgr5:24m2r:241:40digitalmars.com

Bu da güzel bir haber!

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Şimdi, üç "module" dosyasımız var diyelim, bunlar:

  • model.d
  • view.d
  • control.d

Elbette bunların isimleri farklı da olabilir ama MVC olayını tam manasıyla hissedebilmek için şimdilik isimleri böyle olsun. Bu durumda, biz bu üç "module" dosyasını şöyle derleriz:

'dmd sdltest sdl model view control sdl.lib'

'(Derlenen ilk dosya içinde main() var, ikincisinde ise SDL ilintileri...)'

Peki, tıpkı ilk iletimde bahsettim gibi control.d içinde tuşlardaki hareketleri algılayan bir döngümüz olacak. Ancak burada 4 değişken (bool solTuş, sağTuş, üstTuş, altTuş;) model.d dosyası ile haberleşmeli. Aklıma TUŞLAR isminde bir struct oluşturmak ve bahsettiğim değişkenleri kontrolEt() işlevi ile yapılaştırmak geliyor.

Sizce uygun mudur?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Bence de birden fazla kaynak dosyası da olabilir.

http://upload.wikimedia.org/wikipedia/commons/f/fd/MVC-Process.png

Örneğin kullanıcı denetim birimini kullanıyor. Burada model derken oyuncu ya da diğer oyun karakterlerini kasdediyoruz. Gerçekten de aslında bunlar sadece bazı veriler içeriyor. Denetim birimi de bu veriler üzerinde değişiklik yapıyor. Model üzerinde meydana gelen değişiklikleri çizici sınıf ekrana çiziyor. Sonra kullanıcı da bu son değişikleri görmüş oluyor.

İşte bir örnek:

http://www.nuclex.org/images/stories/blog/gamedev/islandwar/islandwar-mvc-design.png

Bu konuda Programming Game AI By Example kitabında sanırım örnekler vardı.

http://amzn.com/1556220782

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

İlk denememi bitirdim, merak edenler buradan deneyebilir: https://github.com/salihdb/MVC

Alıştığımız tek dosyalık örneği +3 parçaya böldüm. Gerçi toplamda 35-45 satırlık 4 dosya ve 156 satır meydana geldi yani kod hacmi büyüdü!

Sanki MVC'nin çok büyük bir esprisi yok gibi. Çünkü bu hale getirmek bana en az 3 kat vakit kaybı getirdi. Üstelik tek dosyanın serbestliği yanında pek tercih edilesi görünmüyor. Hatta control.d içindeki yazılımın sonlanma hadisesini taaa main() içine taşıyabilmek için epey cebelleştim...:)

Bu MVC ne menem bir şeymiş! Özetle 150 KB.'ı geçmeyen Win32 uygulamam geçer oldu. Belki aşağıdaki main()'nin satırı sayısı 3'de 1'e indi ama toplamda 1/3 kat arttı:

import core.stdc.stdio: printf;
import sdl, model, view;

int main(){
  ÇİZ çizmeye;   // model.d
  SAHNE sahne;   // view.d
  //TUŞLAR tuş;    // control.d

  scope(failure) {
     printf("-YAZILIM HATALI SONLANDI-\n");
     printf("=========================\n");
     printf("Hata bilgileri:\n");
  }

  if(SDL_Init(SDL_INIT_VIDEO) < 0) {
     throw new Exception("HATA: Uygun olmayan vidyo!");
  }

  // sahneKur
  SDL_Surface* ekran = SDL_SetVideoMode(sahne.genişliği,sahne.yüksekliği,0,0);

  if(ekran == null) {
     throw new Exception("HATA: Uygun olmayan sahne!");
  }
  scope (exit) { // sahneBitir
     SDL_Quit();
     printf("-YAZILIM HATASIZ SONLANDI-\n");
     printf("Hadi yine iyisin...:)\n");
  }
  int beyaz = SDL_MapRGB(ekran.format, 0xff, 0xff, 0xff);

  SDL_Rect çerçeve;
           çerçeve.w = cast(ushort)(sahne.genişliği - sahne.çerçeveKalınlığı);
           çerçeve.h = cast(ushort)(sahne.yüksekliği - sahne.çerçeveKalınlığı);
           çerçeve.x = cast(short)(ekran.w - çerçeve.w)/2;
           çerçeve.y = cast(short)(ekran.h - çerçeve.h)/2;
  SDL_FillRect(ekran, &çerçeve, beyaz);
  SDL_UpdateRect(ekran, 0, 0, ekran.w, ekran.h);

  return çizmeye.başla(ekran, &çerçeve);  // sonsuz döngü
} // program sonu

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Sanırım model.d'nin içindeki çizim kodları olmaması gerekiyor. Çizim ile kodlar çizicinin view içinde oluyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Alıntı (Salih Dinçer):

>

şuradaki sembol dosyası (https://github.com/erdemoncel/oyun/blob/master/lib/SDL.lib)

Yine ilgisizce ve gereksizce karışıyorum: .lib dosyasına kütüphane demek daha doğru. Sembol dosyalarında yalnızca hata ayıklarken yararlanılan isimler bulunur.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Alıntı (Salih Dinçer):

>

bunlar kafa karıştırıcı

Ben de gerekenden fazlasını bilmiyorum.

Windows ortamındaki kütüphane çeşitleriyle ilgili sorunlar tarihe karışmak üzere. Walter Win64 programı desteğini tamamlamaya çalışıyor:

http://forum.dlang.org/thread/k054e9$1si6$1@digitalmars.com

Özellikle şu yanıtına bakılırsa OMF'ye olan eski bağımlılık ortadan kalkıyormuş:

http://forum.dlang.org/thread/k054e9$1si6$1@digitalmars.com?page=5#post-k0bgr5:24m2r:241:40digitalmars.com

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

August 13, 2012

Fazla incelemiş gibi olmayayım ama "tuş" dediğin an sorumlulukları karıştırmaya başlıyorsun. Bence arayüzde "yön" kavramı bulunmalı. Bu kavram tuşlardan da edinilebilir, fareden de, başka bir şeyden de.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2 3