August 06, 2012

Alıntı (erdem):

>

Alıntı (Salih Dinçer):

>

Peki topun her konum değiştirişte ekranı temizlemek mi gerekecek?

Evet.

Peki bu oyun programlarında hep iki resim bulunduruluyor da bir birisi bir diğeri gösterilmiyor mu? Birinci resim çiziliyor ve grafik kartına "şunu göster" deniyor. O sırada ikinci resmin çizilmesine geçiliyor ve hazır olunca (ve zamanı da gelmişse) "şimdi de şunu göster" deniyor. Mu? :)

Ali

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

August 07, 2012

SDL'de int veri türünün hakim olması ve bizim Vector sınıfında float'ı tercih etmemiz, acaba şu uzayda dolanan topumuzun takılmasına mı sebep oluyor diye düşündüm. Çünkü ondalıklı sayılar SDL_Rect sınıfına dahil olurken tür dönüşümlerine tabi oluyor. Belki aşağı/yukarı yuvarlamalar buna sebep olabilirdi ve denedim...

   private int uzaklık(int x1, int y1, int x2, int y2)
   {
       immutable float araToplam = pow(y2 - y1, 2) + pow(x2 - x1, 2);
       return cast(int)sqrt(araToplam);
   }

Tek tür dönüşümünü yukarıdaki işlevde yaptım ve Vector2 artık bir Vector!int idi. Ancak hiç bir fark yok ki, en azından gözlerim benim yanıltmıyotsa...:)

Demek ki int türünü kullanabiliriz ama hala bir tekleme/takılma sorunu vardı. Bir kaç deneme ile sorunun 60 FPS'e sabitlememizden kaynaklandığını keşfettim. Bunu da şu algoritma ile yapıyoruz. Acaba biraz geliştirsek (en azından bir if daha eklesek) sorunu çözebilir miyiz?

           // bekle
           //*
           if (SDL_GetTicks() - sahneBaşlangıç < 16)
               SDL_Delay(16 - (SDL_GetTicks() - sahneBaşlangıç));//*/

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

August 07, 2012

Alıntı (erdem):

>

Alıntı (Salih Dinçer):

>

Ayrıca konuyla alakalı (gerçek FPS ile hedeflenen FPS'i tutturmak) şu bağlantı (http://sdl.beuc.net/sdl.wiki/Time_Examples)yı görmüştüm. Gerçi biliyor olmalısın...

Evet o bağlantıyı okumuştum.
Dün gece bahsettiğim işlevi (timeLeft'i) denedim de yine aynı...:(

   int timeLeft() {
       uint now = SDL_GetTicks();
       if(sahneBaşlangıç <= now) return 0;
       else return sahneBaşlangıç - now;
   }

   void çalıştır() {
       içerikYükle();
       sahneBaşlangıç += SDL_GetTicks() + 16;
       while (çık != true) {
           güncelle();
           çiz();
           SDL_Delay(timeLeft());
           sahneBaşlangıç += 16;
           /*
           if (SDL_GetTicks() - sahneBaşlangıç < 16)
               SDL_Delay(16 - (SDL_GetTicks() - sahneBaşlangıç));//*/
       }
   }

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

August 07, 2012

Alıntı (Salih Dinçer):

>

Demek ki int türünü kullanabiliriz ama hala bir tekleme/takılma sorunu vardı.

Ben de henüz test edemedim ama sanki öyle hatırlıyorum. Bir de incelediğim diğer kütüphaneler de sanki tamsayı kullanmış gibi hatırlıyorum.

Kişisel tavsiyem bence performansla alakalı iyileştirmelerden önce ilk planda çalışan basit bir örnek kodlamak daha yerinde olur diye düşünüyorum. Çünkü ben de senin gibi ilk planda bu oyun döngüsü vs.. iyileştirmelerle uğraştım. Ama tahminimden çok fazla zaman aldığını görünce sonraya ertelemeye karar verdim.

Örneğin verdiğin örnekteki gibi tuğla kırma gibi bir oyun yapsaydık şunlara ihtiyacımız olacaktı :)

  • Ses kütüphaneleri
  • Çarpışma algılaması
  • Animasyon kütüphanesi

Bunların oldukça vakit alacağını tahmin ediyorum. Ben olsam sanırım tamamen oyun ve oyuncu.d'yi siler sil baştan kodlardım.

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

August 07, 2012

Açıkçası bu soruya net bir cevap verebilecek kadar zeki değilim...:)

Henüz tick kavramını bile anlamaya çalışıyorum! Belki tek anladığım şey sahnedeki nesnelerin güncel durumu ekrana yeniden yansıtıldığında bu bir frame olmakta. Biz bunu kolaylıkla (çünkü sıradan bir döngü ile işimizi hallediyoruz) sayabilmekte, ölçebilmekte ve FPS değeri olarak ekrana yansıtabilmekteyiz.

Belki de sorun tüm sahnenin frame ile ilişkisinden ziyade nesnelerden herhangi birinin sebep olduğu n ms. gecikmesinin, frame içindeki payı (yüzde olarak) önemli. Sanırım bir de konum (x, y) cinsinden bir düzeltme değerine daha ihtiyacımız var. Yani gecikme değeri bir şekilde hesap edilip (oran orantı olabilir) nesnenin konumunu yeniden hesaplatmalı(mı)yız, bilemiyorum... :rolleyes:

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

August 07, 2012

Bekleme süresi en az istediğimiz kadardır ama bazen çok çok daha fazla oluyor. Gerçekte ne kadar beklediğine bakmak ve gerekirse bir veya daha fazla kareyi atlamak doğru olmaz mı?

Ali

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

August 07, 2012

Ben, oyun programcılığını bilmiyorum; siz, bunu herhalde zaten biliyorsunuz ama işletim sistemine 10ms bekle dediğimizde o bizi "en az" o kadar bekletir (üst sınırı yok).

Örnek olarak saniyede 100 kare düşünelim; yani kareler 10ms'de bir gösterilmeli. İşletim sistemi bizi 10ms yerine 30ms bekletmişse bence bu kareden sonraki iki kare için yine 10ms beklememeliyiz. O kareleri ya hiç göstermemeliyiz, ya da onlar için 5ms beklet demeliyiz. Yoksa işletim sisteminin fazladan bekletmeleri nedeniyle herşey yavaş ve tutuk tutuk olur... gibi geliyor bana... :)

Ali

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

August 22, 2012

FPS konusunda SDL'ye biraz güvenim sarsılsa da SDL2'nin başarımı daha iyi görünüyor...

Öncelikle 'SDL_GetTicks()' işlevi, önceki sürümdeki gibi 0'dan başlamıyor! O yüzden aşağıdaki gibi 'main()' işlevi başında ilk değeri almak gerekiyor. Ayrıca daha önce bahsettiğim 'timeLeft()' işlevini de kullanırsak, 120 FPS'de hiç bir sorun yaşatmıyor ve oyun (henüz tam bir oyun sayılmaz!) tam istediğim gibi çalışıyor.

import pencere, nesne, olaylar;
import sdl2d.timer; /* DERLEME PARAMETRELERİ:
dmd oyun pencere nesne olaylar sdl2d/events sdl2d/surface -L-lSDL2 -release */
int loopCounter, startTick;

int timeLeft(int xTick) {
 int now = SDL_GetTicks();
 if(xTick <= now) return 0;
 else return xTick - now;
}
void main(){
 startTick = SDL_GetTicks();
   :    :    :

Tabi ayrıca döngü öncesinde ikinci bir tick değerini aşağıdaki gibi kaydetmemiz de gerekiyor. Sonrası çok basit, işlevi ana döngü içinde kullanmamız yetiyor. Aslında olay geçikme ve hesap (1 FPS = 1000 ms/tick) olmak üzere iki satırdan oluşuyor. Sondaki satırlar şart değil sadece test amaçlı olarak konsola güncel FPS gönderiyor.

 enum FPS = 120;
 int xTick = SDL_GetTicks();
 do {
   SDL_Delay(timeLeft(xTick));
   xTick += 1000 / FPS;
   loopCounter++;
   int clockFPS = (SDL_GetTicks() - startTick)/loopCounter;
   printf("%d(%.1f FPS) \r",
          SDL_GetTicks(), 1000.0 / cast(float)clockFPS);
   :    :    :

Ancak bu FPS'i 120'ye ayarlamama rağmen 125'de sabitleniyor; en azından benim bilgisayarımda. Belki küçük bir püf noktası olabilir veya değeri doğru yansıtmıyor da olabilirim. Neyse denemeyi şuraya (GitHub~sdl2d) (https://github.com/salihdb/sdl2d/) yükledim. Ekran alanı aşağıdaki gibi ve yön tuşları ile karadelik kontrol edilebiliyor. Aslında bunu daha önce yapmıştım ama paylaşmayı unutmuşum.

http://img256.imageshack.us/img256/4130/ekrangrntse.png

Bu şu an için bir oyun değil ama fikir gelirse neden olmasın! Duvarda
sürünen bir karadelik de olabilir bir garip sürüngen de...:)

Başarılar...

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

August 22, 2012

Merhaba Erdem,

Bir takım geometrik şekilleri, ekrana yansıtmadan hafızada nasıl yapabileceğimizi biliyor musun? Aslında bir şeyi denedim ama içime sinmedi. Yani çalışıyor fakat doğru mu yapıyorum emin değilim:

SDL_Surface* boşDöndür() {
 return SDL_SetVideoMode(GENİŞLİK, YÜKSEKLİK, 0, SDL_DOUBLEBUF);
}

Görünüşe göre, yukarıda boş bir yüzey döndürmek yerine, başlangıçta kurulan ana ekranın yeni özellikler ile donatıp adresini döndürmekten başka bir şey yapmıyor. Çünkü SDL_DOUBLEBUF yerine SDL_FULLSCREEN kullandığımda, o satır işletildiği anda ekran tam ekran oluyor... :blush:

Ancak bu dönen değeri (sanırım sadece ana ekranın kopyası?) SDL_DisplayFormat() ile kullandığımda sanki ana ekrandan bağımsız boş yüzeyim oluyor ve orada her türlü oluşturma (generate) ve kesme (mask) işlemi yapabildiğim fark ettim. Yani ortada bir soru/sorun yok gibi ama cevaptan emin değilim...

İşye yukarıdaki işlevi şu şekilde (basit bir örnekle) kullanabiliyorum:

SDL_Surface * yatayKalınÇizgi() {
 SDL_Surface * img = SDL_DisplayFormat(boşDöndür());

 foreach(a; 0..img.pitch) {
   (cast(uint*)img.pixels)
              [img.pitch + a] = 0xFF0000;
 }
 return img;
}

Bir de SDL_MUSTLOCK() kullanmıyorum, kötü yapıyorum dersin?

Teşekkürler...

Alıntı (acehreli):

>

Yine tamsayı bölme işleminin gazabına uğramışsın. :D 1000 / 120'nin sonucu 8.333... değildir. ;)

Lanet olsun, lanet olsun... :-D

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

August 22, 2012

Çalışmaya devam! :) Gayet güzel..

Sadece kodla ilgili ufak bir yorum yapmak istiyorum. 'xTick' gibi değişken isimlerini biraz okunaksız buluyorum. Bunun nedeni de şimdi bu xT ile başladığı için acaba extreme, chrystal mı gibi bir sürü şey aklıma geliyor. Kodu takip etmem zorlaşıyor. Zaten macar notasyonunu da hiç sevmiyordum ;-)

C++'da sınıfların üye değişkenlerini önek ya da sonek' _' kullanan yazım şeklini beğeniyordum. D'de bunların hiç birine gerek bile duymadan aynı ismi veriyorum geçiyor.

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