August 04, 2012

SDL'in yazı tiplerini kullanabilmek için SDL TTF kütüphanesini kurmak gerekiyor.

'$ sudo apt-get install libsdl-ttf2.0-dev'

Henüz bunlar 'sdl.d 'içinde yok. Ama 'usr/include/SDL' dizininde bulunan 'SDL_ttf.h' kütüphanesi için C ilintilerini yazıp bunları 'sdl.d''ye ekleyebilirsin.

Ama bu yukarda verdiğim örnek çok ilginç. Hiç bir kütüphaneye ihtiyaç duymadan 'pbm' biçiminde resim dosyası oluşturabiliyor.

Örneğin bu adreste bulunan circle1.c (https://banu.com/blog/7/drawing-circles/circle1.c) dosyasını derlersen bir tane çember oluşturuyor. Çok güzel bir olay hatta aynı kodun D versiyonunu yazabiliriz. Ama ben şimdilik paralel port ile ilgili örneği tamamlamayı düşünüyorum. Bir haftadır hala yazamadım :-)

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

August 04, 2012

Merhaba Erdem,

İlintiyi sdl.d (https://github.com/erdemoncel/oyun/blob/master/src/sdl.d)'ye ekledim ama çalıştırmada başarılı olamadım! Kafamı karıştıran bazı şeyler vardı. Örneğin hiç bir elemanı olmayan TTF_font'a anlam veremedim. Ben de hata vermesin diye hiç bir elemanı olmayan yapı ekledim. Ayrıca hata atan/yaklayan iki takma isim gördüm. Bunlara da anlam veremedim...:)

/* The internal structure containing font information */
typedef struct _TTF_Font TTF_Font;
. .
/* We'll use SDL for reporting errors */
#define TTF_SetError	SDL_SetError
#define TTF_GetError	SDL_GetError

Ben de son iki satırı gizledim...

Bu ilintiyi en sona (664. satır) şu başlıkla ekledim:

'extern(C) // dmd sdl -debug -L-lSDL -L-lSDL_ttf'

Ayrıca ferdi şekilde derleyebilmek için basit bir debug subroutine'i yazdım. Bir kaç düzeltmeyi ve eklemeyi de saymazsak bu kadar. Son olarak bir şey dikkatimi çekti SDL_Surface*'in iki tane takma ismi var. Bence Grafik2D'yi silelim ama sınıflarda anlamı arttırıyorsa sen bilirsin.

Renk yapısına bir kaç renk daha eklesek mi? Ben turkuaz ve siyah olmak üzere iki tane ekledim ama temel renkler dışında sarı ve gri tonları gibi renkler hoş olabilir. Neyse bunlar küçük ayrıntılar. Asıl meseleye (ekrana yazı yazamamaya) gelirsek...:)

Önce herhangi bir TTF font'u bulup aynı dizine kopyaladım ve aşağıdakine benzer şekilde yükledim. Burada sorun yok!

class Oyun : TemelOyun
{
   :    :    :
   TTF_Font * font;

   this(int genişlik, int yükseklik, int çözünürlük = 0) {
       :    :    :
       font =  TTF_OpenFont("arial.ttf", 16);
   }
}

Ayrıca her şey kitabına göre olsun diye destructor'e de şu satırları ekledim:

       TTF_CloseFont(font);
       font = null;
       TTF_Quit();

Son olarak bize bir işlev lazımdı o da şu olsa gerek:

   public int ekranaYaz (SDL_Surface* screen, TTF_Font* font, const char* text)
   {
       auto color = SDL_Color(255, 255, 255, 0);
       SDL_Surface* text_surface;

       text_surface = TTF_RenderText_Solid(font, text, color);
       if (text_surface != null)
       {
           SDL_BlitSurface(text_surface, null, screen, null);
           SDL_FreeSurface(text_surface);
           return 1;
       } else {
           // report error
           return 0;
       }
   }

Ancak hata da vermiyor, çalışmıyor da... :rolleyes:

Herhalde eksik bir şeyler olsa gerek. Sanırım yazıyı taşıyan bir nesne olması gerekiyor. Bu nesnenin de konum bilgisi gibi ama başta belirttiğim gibi boş yapıyı nasıl dolduracağız? Örneğin şu işlev ile şekillendirebiliriz ama tek başına kullandığımda program çöküyor...

      //TTF_SetFontStyle(font, TTF_STYLE_NORMAL);

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

August 04, 2012

Alıntı (Salih Dinçer):

>

İlintiyi sdl.d (https://github.com/erdemoncel/oyun/blob/master/src/sdl.d)'ye ekledim ama çalıştırmada başarılı olamadım! Kafamı karıştıran bazı şeyler vardı. Örneğin hiç bir elemanı olmayan TTF_font'a anlam veremedim.

Aslında o yapılar boş değil. Ama sadece yapının bildirim kısmı var. Yapının detayları da c kaynak dosyalarındadır sanırım.

Alıntı (Salih Dinçer):

>

Bence Grafik2D'yi silelim ama sınıflarda anlamı arttırıyorsa sen bilirsin.

Onu sanki cizici.d'de grafik çiz demek bana daha doğal göründüğü için eklemiştim.

https://github.com/erdemoncel/oyun/blob/master/src/cizici.d

Alıntı (Salih Dinçer):

>

Renk yapısına bir kaç renk daha eklesek mi? Ben turkuaz ve siyah olmak üzere iki tane ekledim ama temel renkler dışında sarı ve gri tonları gibi renkler hoş olabilir. Neyse bunlar küçük ayrıntılar.

Tabi istediğin kadar renk ekleyebilirsin :-)

Alıntı (Salih Dinçer):

>

Hatta ActionScript3 ile yazılan oyunlarda bile kayıt edilmiş PNG görüntüleri kullanıldığını hatırlıyorum. Resmi haritalayarak ekrana yazı ve bilimum simge yazıyorlardı...:)

Bir de bu kütüphaneyi de yeni gördüm. Resim dosyalarını png ya da jpeg olarak kodlayabiliyormuş.

https://github.com/callumenator/imaged

Dikkat ettim de burada 'simpledisplay.d' de oluşturduğu renk yapısı bizimkinin aynısı :-D

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

August 04, 2012

Alıntı (erdem):

>

Alıntı (Salih Dinçer):

>

İlintiyi sdl.d (https://github.com/erdemoncel/oyun/blob/master/src/sdl.d)'ye ekledim ama çalıştırmada başarılı olamadım! Kafamı karıştıran bazı şeyler vardı. Örneğin hiç bir elemanı olmayan TTF_font'a anlam veremedim.

Aslında o yapılar boş değil. Ama sadece yapının bildirim kısmı var. Yapının detayları da c kaynak dosyalarındadır sanırım.

Evet, kaynak kodu (http://hg.libsdl.org/SDL_ttf/file/097c30e9d4ed/SDL_ttf.c)na şimdi baktım da yapının üyeleri belli. İşin ilginci, sanırım FreeType ilintisi de yazmamız gerekebilir...:)

Alıntı (erdem):

>

Bir de bu kütüphaneyi de yeni gördüm. Resim dosyalarını png ya da jpeg olarak kodlayabiliyormuş.

https://github.com/callumenator/imaged

Dikkat ettim de burada 'simpledisplay.d' de oluşturduğu renk yapısı bizimkinin aynısı :-D

Derledim çalışıyor...:)

Bu SDL'nin de simple'ı ve bazı basit işlerde kullanabilir ve kaynak kodundaki olaylardan (örneğin import io = std.stdio; diye bir olay varmış!) bir şeyler öğrenebiliriz. Gerçi derleme boyutu aşırı büyük görünüyor. Tabi işletim sisteminin kütüphanelerini saymazsak aracı kullanmıyor herhalde ondan.

SDL'yi çok sevdim çünkü dosya boyutu da genelde 300 KB. civarında. Kütüphaneleri desen bir elin parmakları sayısınca. GtkD'ye göre öz ve kolay geliştirme ortamı sunuyor. Oyun harici şeylerin de yapılabileceğini düşünüyorum.

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

August 04, 2012

Sonunda biraz uğraşarak da olsa bir test dosyası oluşturarak çalıştırabildim :-)

http://ehobi.org/resim/resim/merhabad.png

TTF kütüphanesini denemek için 'make font' demek yeterli. Oluşturduğum dosya da demos dizininde 'yazitipi.d' dosyası. Eğer hala denemediysen' make pong' diyerek başka bir programı da deneyebilirsin.

Bu arada sana hak verdim. Gerçekten kod şu an benim için bile karman çorman olmuş :-D

Eğer uğraşmak istiyorsan oldukça elden geçirmen gerekecek :)

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

August 05, 2012

Alıntı (erdem):

>

Sonunda biraz uğraşarak da olsa bir test dosyası oluşturarak çalıştırabildim :-)
Eline sağlık...

Meğer TTF_Init() yapmayı ihmal etmişim. Bir de koordinatı hiç düşünmemiştim. Renk olayını da ekleyince şu iki satırla artık ekranın istediğim yerine yazı yazabiliyorum, teşekkürler...:)

     TTF_SetFontStyle(courier_TTF, TTF_STYLE_BOLD);
     ekranaYaz(courier_TTF, Renk.beyaz, ekrangenişlik/2, ekranyükseklik/2,
                                                      "Merhaba (D)ünya!");

http://img100.imageshack.us/img100/2427/planei.png

Alıntı (erdem):

>

TTF kütüphanesini denemek için 'make font' demek yeterli. Oluşturduğum dosya da demos dizininde 'yazitipi.d' dosyası. Eğer hala denemediysen' make pong' diyerek başka bir programı da deneyebilirsin.
O toplu uygulamayı denemez olur muyum! Hatta en çok hoşuma gideni oldu. Bir de temasEtti_mi() olayını yapabilirsek harika olacağını düşünüyorum. Ama sanki önce hata sınıfını ilintilemeliyiz. Çünkü az önce uğraşırken dosya hatalarını yakalayamadım. Şöyle denemeler (SDL_RWops ile) de yaptım ama olmadı...:(

       TTF_Init();
       arial_TTF =  TTF_OpenFont("arial.ttf", 40);
       comic_TTF = TTF_OpenFont("comics.ttf", 40);/*
       SDL_RWops *rw = SDL_RWFromFile("comics.ttf", "rb");
       printf("Buraya gelemedim...:(");
       comic_TTF = TTF_OpenFontIndexRW(rw, 1, 40, 0);
       assert(rw != null);//*/
       courier_TTF = TTF_OpenFont("courier.ttf", 40);

Alıntı (erdem):

>

Bu arada sana hak verdim. Gerçekten kod şu an benim için bile karman çorman olmuş :-D

Eğer uğraşmak istiyorsan oldukça elden geçirmen gerekecek :)

Estağfirullah, kodlar gayet yerinde. Ama sanki biraz sınıfları azaltsak sanki daha iyi olacak. Aslında ben bunu yaptım ve üçe (Oyun, Oyuncu ve Çizici) indirdim. Sanki TemelOyun sınıfı biraz kafa karıştırıyor. Yani o sınıfı uygulama içinde başka anda çağırmayı düşünüyor musun? Belki de Oyun sınıfıyla birleşmesinde bir sakınca yoktur. Böylece super()'ler ile uğraşmayız ve kod biraz kısalır...

Bu arada ekranaYaz() işlevini Oyun sınıfına dahil ettim ve son hali şöyle:
'(Belki ismi sadece Yaz() da olabilirdi...)'

public bool ekranaYaz (TTF_Font* xFont, Renk xRenk,
                         int x, int y, const char* metin) {

       auto rengi = SDL_Color(xRenk.k, xRenk.y, xRenk.m);
       EkranYüzeyi textSurface = TTF_RenderUTF8_Solid(xFont, metin, rengi);
       SDL_Rect pixelCoordinate;
                pixelCoordinate.x = cast(short)x;
                pixelCoordinate.y = cast(short)y;

       if(!TTF_WasInit())
       {
           printf("YAZI HATASI: TTF sunucusu ilklendirilemedi!\n");
           return false;
       }
       else if(xFont == null)/*
       else if(TTF_FontHeight(xFont) <= 0)//*/
       {
           printf("YAZI HATASI: TTF dosyası yüklenemedi! %d\n");
           return false;
       }
       else if (textSurface != null)
       {
           pixelCoordinate.x -= cast(short)textSurface.w/2;
           pixelCoordinate.y -= cast(short)textSurface.h/2;
           /* DİKKAT:
            * Parçalama hatası vermemesi için koordinatın
            * ekrana ortalanması burada hesaplanmalı...
            */
           SDL_BlitSurface(textSurface, null, ekran, &  pixelCoordinate);
           SDL_FreeSurface(textSurface);
           return true;
       }
       else  // Hiç biri de değilse ekran'a bir şey yazma...
       {
           printf("YAZI HATASI: Görülebilir (render) hale getirilemedi!\n");
           return false;
       }
   }

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

August 05, 2012

Alıntı (Salih Dinçer):

>

Renk olayını da ekleyince şu iki satırla artık ekranın istediğim yerine yazı yazabiliyorum, teşekkürler...:)

Gayet güzel! :-p Tebrikler..

Alıntı:

>

Ama sanki biraz sınıfları azaltsak sanki daha iyi olacak. Aslında ben bunu yaptım ve üçe (Oyun, Oyuncu ve Çizici) indirdim. Sanki TemelOyun sınıfı biraz kafa karıştırıyor. Yani o sınıfı uygulama içinde başka anda çağırmayı düşünüyor musun? Belki de Oyun sınıfıyla birleşmesinde bir sakınca yoktur. Böylece super()'ler ile uğraşmayız ve kod biraz kısalır...

Aynen tamamen katılıyorum. Hatta belki Oyun ve TemelOyun sınıflarını tamamen kaldırıp programcı için daha da esneklik sağlanabilir.

Bir de dikkat edersen burada mantık hep aynı. Yani oyun nesneleri ilkönce yükleniyor. Bu yüzden icerik.d'ye yazıtipi yükle şeklinde bir işlev eklenebilir. Daha sonra kaynaklar ilklendiriliyor, oyun içinde kullanılıyor ve daha sonra geri veriliyor.

Bu durumda benim yaptığımı örnekte biraz hızlı yazdığım için öyle değildi. Ama TTF yazıtipi de aslında çizilebilen bir oyun nesnesi. Bu yüzden aslında oyun nesneleri için kullandığımız oyuncu.d'de ilklendirilmesi daha mantıklı. Çünkü dikkat edersen her oyun nesnesinin bir SDL_Surface * (ben buna 2D grafik) diyorum. Sonra o grafiğin tamamının mı yoksa bir parçasının mı kullanılacağını gösteren SDL_Rect türünde bir alan belirten özelliği var.

İster TTF yazıtipi olsun isterse bir resim dosyası olsun ilkönce ekran kartının belleğinde o yüzeyler kesiliyor. Ne kadarlık bir alanı keseceğimiz ise SDL_Rect belirliyor. Daha sonra bellekte bunlar birbiri üzerine kesilip yapıştırıldıktan sonra ekrana basılıyor. Bu yüzden yazıtipinin de bir oyun nesnesi olması daha mantıklı.

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

August 05, 2012

Merhaba Erdem,

Az önce basit olsun diye tek sınıflı bir uygulama yazdım. Tabi bunun çalışması için herhangi bir PNG ve TTF dosyasına ihtiyacınız olsa da internette bulduğum şu dosyalarla daha hoş görünüyor:

/*
uçaklar.d (05.08.2012)
*/
import sdl, core.stdc.stdio: printf;

class Sahne {
 int genişliği, yüksekliği, çözünürlüğü;
 Renk zeminRengi;
 SDL_Surface* ekranı;
 TTF_Font* arial_TTF;
 uint sahneBaşlangıç;

 this (int genişlik, int yükseklik, Renk zemin, int çözünürlük = 0) {
   this.genişliği = genişlik;
   this.yüksekliği = yükseklik;
   this.çözünürlüğü = çözünürlük;
   this.zeminRengi = zemin;

   SDL_Init(SDL_INIT_EVERYTHING);
   TTF_Init();

   ekranı = SDL_SetVideoMode(genişliği, yüksekliği, çözünürlüğü, SDL_HWSURFACE);
   temizle(zemin);
 }

 @property void temizle (Renk zemin) {
   SDL_FillRect(ekranı, &ekranı.clip_rect,
             SDL_MapRGB (ekranı.format, zemin.k, zemin.y, zemin.m));
   güncelle();  // Bu satır olmadığında değişiklikler sahneye yansımıyor!
 }

 @property void güncelle () {
   SDL_Flip(ekranı);
 }

 @property bool resimYükle (string dosya, bool şeffaflık = true) {
   bool sonuç = true;
   SDL_Surface * geçiciNesne;

   geçiciNesne = IMG_Load(dosya.ptr);
   if(geçiciNesne == null) {
     printf("DOSYA HATASI: Resim dosyası yüklenemedi!\n");
     sonuç = false;
   }
   nesneYükle(geçiciNesne);
   return sonuç;
 }

 @property bool yazıtipiYükle (string dosya, int büyüklük = 16) {
   bool sonuç = true;
   TTF_Font * geçiciNesne;

   geçiciNesne = TTF_OpenFont (dosya.ptr, büyüklük);
   if(geçiciNesne == null) {
     printf("DOSYA HATASI: TTF dosyası yüklenemedi!\n");
     sonuç = false;
   }
   arial_TTF = geçiciNesne;
   return sonuç;
 }

 @property void nesneYükle(SDL_Surface* nesne) {
     SDL_BlitSurface(nesne, null, ekranı, null);
     SDL_FreeSurface(nesne);
 }

 ~this() {
   SDL_FreeSurface(ekranı);
   TTF_CloseFont(arial_TTF);
   arial_TTF = null;
   TTF_Quit();
   SDL_Quit();
 }
}

void main() {
 with (new Sahne(250, 250, Renk.turkuaz)) {
   resimYükle("Plane.png");

   if(yazıtipiYükle("PLANES__.TTF", 100))
     nesneYükle(TTF_RenderText_Solid(arial_TTF, "A",
                      SDL_Color(255, 255, 255, 0)));
   güncelle();
   SDL_Delay(3000);

   temizle(Renk.beyaz);
   SDL_Delay(300);
 }
}/*
 * SDL ilintisi için: https://github.com/erdemoncel/oyun/blob/master/src/sdl.d
 * SDL yüklemek için: sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev
 * Derlemek için: dmd uçaklar.d sdl -L-lSDL -L-lSDL_image -L-lSDL_ttf -release
 */

Derleme talimatları hemen yukarıda ve her şey olumlu giderse ilk aşamada şu ekranı görmeniz gerekiyor:
http://img337.imageshack.us/img337/9783/planesa.png

Henüz çok eksiği var ve bence en başta Nesne isminde bir sınıfa ihtiyaç var. Çünkü yüklenen nesnelerin koordinatları, rengi gibi şeyler olmalı. Sanırım 100 satırı geçmeyen bu uygulama zamanla daha da karışacak...:)

Dip Not: Çok karışmasın diye ekranaYaz() işlevine ve bir çok şeye (örn. nokta, çizgi ve şekil çizme işlevleri) yer verilmemiştir.

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

August 05, 2012

Alıntı (erdem):

>

İster TTF yazıtipi olsun isterse bir resim dosyası olsun ilkönce ekran kartının belleğinde o yüzeyler kesiliyor. Ne kadarlık bir alanı keseceğimiz ise SDL_Rect belirliyor. Daha sonra bellekte bunlar birbiri üzerine kesilip yapıştırıldıktan sonra ekrana basılıyor. Bu yüzden yazıtipinin de bir oyun nesnesi olması daha mantıklı.

Erdem, bu SDL_Rect bir tür maske gibi işleve sahip değil mi? Hani Dörtgen olarak takma isimi olan yapı. Gerçi bu yapının içinde yükseklik ve genişliği de var. Tam da Nesne sınıfı olacak bir yapı sanki, ne dersin?

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

August 05, 2012

Ben çok beğendim. Bence bunu Makefile dosyasına ekleyip demos bölümüne eklemelisin :)

Alıntı (Salih Dinçer):

>

Erdem, bu SDL_Rect bir tür maske gibi işleve sahip değil mi? Hani Dörtgen olarak takma isimi olan yapı. Gerçi bu yapının içinde yükseklik ve genişliği de var. Tam da Nesne sınıfı olacak bir yapı sanki, ne dersin?

SDL_Rect basit bir C yapısı.

http://sdl.beuc.net/sdl.wiki/SDL_Rect

Basitçe bir dikdörtgenin koordinatlarını tutuyor. Bunu da iki tane ekran yüzeyi ekran kartının belleği üzerinde birbiri üzerine yapıştırılırken blit kullanılıyor. Benim düşüncem her oyun nesnesi bir SDL_Surface ve SDL_Rect'e sahip olmalı.

Kullanımını da şöyle düşünebilirsin. Örneğin hareketli bir Pacman yapmak istiyoruz. Ama dikkat edersen Pacman'ın hareketini gösteren resim dosyaları aslında tek bir resim dosyasında oluyor. Sonra bu dörtgen yapıyı kullanarak bu resim dosyasının hangi kısmını göstereceğimizi belirtiyoruz. Ve arada bir süre bekleyerek hareketli bir animasyon oluşturuyoruz.

Bu arada şu şekilde ilklendirilebiliyormuş.

   SDL_Rect konum = {0,0,600,400};

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