folder Tahribat.com Forumları
linefolder C - C++
linefolder C++ / SDL2 Çarpışma Ve Kamera Problemi



C++ / SDL2 Çarpışma Ve Kamera Problemi

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Waze
    Waze's avatar
    Kayıt Tarihi: 01/Ekim/2012
    Erkek

    Merhaba, yine ben. :P Üç tane sorunum var.

    1. sorun: Entity'lerin sprite'ları ekrana çizilirken her zaman listedeki ilk eleman kamera sağa sola kaydırıldıkça yamuluyor.

    NOT: 2. düzeldi.
    2: sorun: Her entity'nin çarpışma kontrolü yapan hitBox'ı var. Bu x, y, w, h şeklinde normal dörtgen. Player platformun üzerinde yürürken tam üzerinde durması gerekirken her zaman biraz içine giriyor diğer hitBox'ın.

    Anlatamama ihtimalime karşı video çektim: https://www.youtube.com/watch?v=MFlk0qdkoz8

    Önemli olan sorunum ikincisi. Bunun çarpışma kontrolü yaptıkan sonra velocity'leri ayarlarken yaptığım bir yanlışlıktan ortaya çıktığını düşünüyorum.

    1. Çarpışma kontrolü yapılıyor.
    2. Eğer çarpışma yoksa yer çekimi uygulanıyor. (Şimdilik herhangi birşeyle kontrol ediyor ama ileride Platform diye ayrı bir Entity oluşturağım)
    4. Eğer Entity başka biriyle temas halindeyse (yani Player yere basıyorsa) ve Y ekseni sıfırdan büyükse (aşağı doğru ise) Y eksenindeki velocity sıfırlanıyor. Bunu Player'in platform üzerinde durabilmesi için yaptım, aksi halde sonsuza kadar düşüyor.
    3. Gravity ve uygulanan ekstra velocity (zıplama, yürüme vs.) Entity'ye (burada Player) uygulanıp yeni pozisyonu ayarlanıyor.

    Nesne kalıtımları şöyle:
    Entity > DynamicEntity > AnimatedEntity > Character > Player
    Platformlar şimdilik sadece Entity.

    Çalışma düzeni şöyle:
    1. GameEngine::Update > EntityManager::Update
    2. EntityManager::Update > (tüm Entity'leri gezen döngü içinde) > Çarpışma Kontrolü (çarpışma varsa isColliding = true yapıyor) > Entity::Update (Player için aşağıdaki gibi işliyor)
    3. Player::Update > Klavye Girdisini Al (zıpla, yürü vs.) > Character::Update
    4. Character::Update >DynamicEntity::Update
    5. DynamicEntity::Update >
        5.1 - Çarpışma varsa isOnGround = true;
        5.2 - Eğer Entity yerde değilde yer çekimi uygula. (1px)
        5.3 - Eğer Entity yerde ise ve velocity > 0 ise; velocity.y = 0
        5.4 - DynamicEntity::CompleteMovement(); >
                5.4.1 - Entity.x'e velocity.x'i ekle. (rect.x += velocity.x)
                5.4.2 - velocity.x = 0
                5.4.3 - Entity.y'ye velocity.y'yi ekle. (rect.y += velocity.y)
                5.4.3 - velocity.y sıfırlama çünkü sadece yer çekimi tarafından etki edilebilir.
        5.5 - AnimatedEntity::Update()
                 5.5.1 - Animate();  (Animasyon karesini ayarlıyor sorunla alakası olduğunu sanmıyorum)
                 5.5.2 - Entity::Update();  (Şimdilik boş.)

    Methodlar aşağıdaki gibi:
    Player::Update: http://paste.ubuntu.com/13365797/
    DynamicEntity::Update: http://paste.ubuntu.com/13365810/
    DynamicEntity::CompleteMovement: http://paste.ubuntu.com/13365817/

    Hahaha şaka gibi :D
    ApplyVelocity isimli iki methodum vardı. Birisi Vector2 diğeri int, int parametreleri alıyordu. Birinde MAX_SPEED kontrolü yapıp diğerinde yapmamışım. Onu düzeltince sorun halloldu.
    Geçen başlıktaki gibi oldu.
    Soruyu silmiyorum belki birisi daha karşılaşır.

    3. sorun: Player ve Character nesneleri klavye girdisine ihtiyac duyuyor. Bu yüzden Update methodları (const unsigned char* keyboardState) alıyor.
    Ancak Platformlar için bu durum geçerli değil. Sadece gravity'yi almaları yeterli. (StaticEntity diye bir sınıf daha yapmayı planlıyorum, orada gravity de gereksiz olacak)

    Ama EntityManager içinde tüm Entity'lerin Update methoduna iki parametre gönderiliyor. Dolayısıyla hata veriyor.

    Bu sorunu aşmak için Entity içinde iki Update methodu tanımladım. Birisi parametreleri alıyor, diğeri almıyor.
    Parametre alan method EntityManager tarafından tetiklendiğinde onun içinde parametresiz method çağırılıyor.
    Bu geçici bir çözüm, nasıl daha yakışıklı bir çözüm getirilebilir?

    bonus: Debug için gdb kullanmak istiyorum. Şöyle yapıyorum;
    1 - gdb bin/binary
    2 - (gdb) run

    Ancak bana gcc'nin verdiğinden farklı bir sonuç getirmiyor. İnternetten okuduğum kadarıyla başka birşey gerekmiyor.
    Yani eğer aynı şeyleri söyleyecekse bana, insanlar neden kullanıyor ki? Birşeyleri yanlış yapıyorum sanırım..

  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    YeniHarman
    YeniHarman's avatar
    Kayıt Tarihi: 17/Haziran/2012
    Erkek

    İlk sorun: https://en.wikipedia.org/wiki/Screen_tearing

    İkinci sorun: Yükseklik vs. ekranın neresinden hesaplanıyor? Ağırlık merkezi ile hesaplaman kolaylık sağlar. Bu yolla x1,y1 ==> y1 + h / 2 ; x1 + w / 2 ekrandaki koordinatlar olabilir. Belki de burada ufak bir kod hatası vardır:)

    Üçüncü sorun: İşte player farklı bir şey. Player diye bir nesnem olacaksa, kullanıcının girdilerini kontrol etmeli hatta ayrı bir threadda çalışmalı:)

    Dördüncü sorun: gcc derleyici, nasıl gdb ile aynı çıktıyı üretebilir ki? gdb ile yapmak istediğiniz nedir?


    Olaylara karışmayın!
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Waze
    Waze's avatar
    Kayıt Tarihi: 01/Ekim/2012
    Erkek
    YeniHarman bunu yazdı

    İlk sorun: https://en.wikipedia.org/wiki/Screen_tearing

    İkinci sorun: Yükseklik vs. ekranın neresinden hesaplanıyor? Ağırlık merkezi ile hesaplaman kolaylık sağlar. Bu yolla x1,y1 ==> y1 + h / 2 ; x1 + w / 2 ekrandaki koordinatlar olabilir. Belki de burada ufak bir kod hatası vardır:)

    Üçüncü sorun: İşte player farklı bir şey. Player diye bir nesnem olacaksa, kullanıcının girdilerini kontrol etmeli hatta ayrı bir threadda çalışmalı:)

    Dördüncü sorun: gcc derleyici, nasıl gdb ile aynı çıktıyı üretebilir ki? gdb ile yapmak istediğiniz nedir?

    1. cevaba bakıyorum.
    2. sorunu max_speed i kısıtlayarak hallettim.
    3. Sadece player için değil, oyun içinde düşmanlar veya herhangi DynamicEntity'ler olacak, aynı sorun o zaman da ortaya çıkacak.
    4. Çıktıdan kastım hata metinleri, örneğin gcc'den memory corrupted hatası alıyorum, gdb'den daha ayrıntılı bir mesaj bekliyorum ama aynı şeyi söylüyor. Ya da sadece bu durum için de geçerli olabilir bilmiyorum.

    Teşekkürler cevap için, screen tearing olayına bakıyorum.

  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    Waze
    Waze's avatar
    Kayıt Tarihi: 01/Ekim/2012
    Erkek

    Anladığım kadarıyla olay ekranın yenilenme hızıyla alakalıymış. Sorunun çözümü olarak da çoğu kişi render ve update hızını sabitlemeye çalışmış. SDL1'de yenilenme hızı performansa göre belirlenirken (zorla da 60hz çalıştırma imkanı varmış) SDL2'de varsayılan olarak 60hz'e çıkmaya çalışıyormuş.

    Şunları denedim:
    * (Aynı sitede bahsedilen Timer sınıfını oluşturmak için bi tutorial daha var)
    * (Yorumdaki SetHint olayı. Ama sanırım o da default olarak uygulanıyormuş)
    * (Onaylanan cevaptaki EDİT kısmındaki çözüm)
    * (Burada DOUBLEBUFF diye bi flag var ama SDL2'de kaldırılmış sanırım)
    * (Burada SetVideoMode'un yeni halini göstermiş ama flag'ler ile ilgili bir bilgi yok)
    * (Burada adam SDL_putenv ile birşeyler yapmış ama sadece Windows dediği için denemedim. Bu da SDL1.)
    * (Bunları ekleyince nedense daha kötü bir hal aldı :( ben de kaldırdım tekrar)
    * (Şurada adam render'ı sabitlemiş Timer ile ama sanırım SDL_Delay ile aynı sonucu doğurur. Hemen altındaki de stackoverflow'daki ile aynı çözüm. Bir de şu sorunu hallettikten sonra Update'i asenkron çalıştırıp animasyon ve hareketleri FPS'den bağımsız hale getirmeye çalışacağım. Çünkü bu methodların çalıştırılma hızı monitör hızını değiştiriyor, bu değişim de animasyon ve hareketin hızlı/yavaş olmasını sağlıyormuş.)

    Bin nasihat bir müsibet demişler baya birşey öğrendim ama sonuç yine aynı...

    Acaba diyorum benim ekran kartı sürücülerim ile ilgili bir problem olabilir mi? (Geçenlerde OpenGL kurmak için güncellemiştim)
    Ubuntu kullanıyorum, sürücüleri diğer platformlara göre biraz geridedir belki de.

     edit:

    Sorun bende olabilir diye şuradaki çözümü denedim, sanki biraz daha iyi gibi ama denk mi geldi bilmiyorum. Çünkü her zaman aynı şekilde bozulma olmuyor, bazen daha az oluyor.
    Şuradaki cevaptaki güncellemeleri de yaptım. Sanırım ekran kartıyla ilgili bir problem değil.

     

     

    Waze tarafından 21/Kas/15 03:55 tarihinde düzenlenmiştir
Toplam Hit: 1735 Toplam Mesaj: 3
c++ game development oop sdl2 gdb