Kabarma hızını artır


9

Ben PyGame 2d sidescroller üzerinde çalışıyorum. Her harita için bir doku kullanıyoruz (bu, dokunun gerçek boyutudur):

harita doku

Sonra görüntüyü bu kodla yüklüyoruz:

sprite = pygame.image.load("Maps/MapTesting.png")
sprite.convert()
sprite = pygame.transform.scale(sprite,
              (sprite.get_width()*6, sprite.get_height()*6))

Gördüğünüz gibi, doku gerçek harita dokusunu oluşturmak için 6 kez havaya uçuyor. Ortalama olarak bu doku yaklaşık 4500x800'dür. Bu doku her karede ekrana köreltilmelidir , çünkü tüm ekran kirli (yan kaydırma sayesinde). Bunu şu kodu kullanarak yapıyoruz:

screen.blit(sprite, (0, 0),
(cameraposx, cameraposy, windowheight, windowwidth))

Ve çalışıyor. Sorun şu ki oldukça yavaş: Düşük düzgün bir bilgisayarda yetersiz 40 FPS alıyorum ve 60 FPS'yi hedeflerken, gerçek AI / nesnelerden herhangi biri olmadan. Bunu nasıl hızlandırabiliriz?


Yukarıdaki kodun sterilize edildiğini ve bağlamın dışına çıkarıldığını unutmayın. Kodun tamamını burada bulabilirsiniz: https://github.com/nightcracker/PyGG2

Son olarak, yukarıdaki görüntü 8 bit gibi görünse de, oyunda daha fazla bit derinliği gerektiren öğeler var.


Doku başına aklı başında bir boyuta bölün, örneğin blok başına 1024 genişliğinde ve sadece bir seferde alakalı olan ikisini karıştırın.
Jari Komppa

@JariKomppa: Denedim, blitting üzerinde hiçbir etkisi yoktur (pygame sadece söyledim rektini blit edecek kadar akıllıdır), sadece bellek kullanımı.
orlp

Sen ... oyununu kullanamazsın (trollface.jpg) .... jkjk, bu durumda yavaşlamanın meydana geldiği yer olmadığını tahmin ediyorum, kapsamlı bir şekilde test ettin mi?
ultifinitus

@ultifinitus: Evet, cProfile ile profilli oldum.
orlp

Gerçek çözünürlükte görüntülerseniz hız farkı nedir? Büyük resmi önceden hesaplarsanız ne olur?
ultifinitus

Yanıtlar:


7

Pikselleri bir yüzeye bölme ile ilgili genel karşılaştırmalı optimizasyonları listeleyeyim (deneyimimden).

1) Genellikle palet görüntüleri (indekslenmiş görüntüler) örtüldüğünde, ek bir yönlendirme seviyesine (renk elde etmek için) girer. Böylece gerçek renkli görüntülerle karşılaştırıldığında blitting yaparken yavaş olacaktır.

2) Gerçek renk piksel verileri (With Out Alpha - say24 bit veri olduğunu varsayalım) görüntünün her tarama hattı için (görüntünün bir bölümünü kopyalıyorsak) cihaz çerçeve arabelleğine bir memcpy yapabileceğimiz için çok hızlı bir şekilde körleştirilebilir Örtülecek veriler tam bir görüntü ise, daha hızlı olan tüm verileri doğrudan memcpy edebiliriz!

3) Alfa piksel verilerinin karıştırılması, her bileşen sonucunun hesaplanmasını içereceğinden ve RGB verilerine tekrar paketlememiz gerektiğinden en pahalısı olacaktır. Basit bir şekilde, son renk elde etmek için her piksel için daha fazla işlem!

Finalrgb = Alpha*(Srgb) + (1-Alpha)*Drgb (this is for normal blend equation)
    where Srgb is source-rgb (we need to apply for each of the component for final color)
       Drgb is the color that will be there in the destination buffer.

Daha önce pyGame üzerinde çalışmadım.Ayrıca, sos koduna hızlı bir bakış, kaputun altında 'sdl' Blit işlevlerini kullandığını varsaymama neden oldu. Genellikle Sdl blit çok daha hızlı ve optimize olacak, bu yüzden yukarıdaki noktaları ve profili bir kez daha yapmayın! İyi şanslar!

* Güncelleme: * Renk tuşunu ayarlamak, her pikseli yüzeye karıştırırken ekstra bir kontrol eklemek gibidir.

       for(eachPixelColor in allPixels)
         {
            if(eachPixelColor is NOT colorKeyColor)
            {
              copy color to the frame buffer!
            }

         }

Yani, burada görürseniz, her pikselin renk geçerliliğini kontrol etmemiz gerektiğinden memcpy kullanmamakla sınırlıyız!


Tamam, set_colorkeyharita dokusuna kaymış bir çağrı olduğu için (pahalı) bir alfa kanalı verir. Bu convertdüzeltildi ve şimdi bu bok PC'de 150 FPS kararlı çalışıyorum. Teşekkürler!
orlp

hey renk anahtarı ile ilgili düzenleme yapacak abt it bazı bilgileri eklemeyi bile unuttum: D
Ayyappa

5

sprite.convert() düşündüğünü yapmaz.

sprite = sprite.convert() ihtiyacınız olan şey bu.


Woops, ben sprite = sprite.convert()gerçek kod olsa var :)
orlp

Aha, güzel. :) Bu durumda, pygame yerine pyglet kullanmayı veya OpenGL ile rahatsanız doğrudan pyOpenGL'yi kullanmayı düşünmek dışında size sunacak çok şeyim yok.
Kylotan

@Kylotan: iyi yakalanma dostum! ben kontrol
etmedim

veya daha da iyisi:sprite = pygame.image.load("Maps/MapTesting.png").convert()
MestreLion
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.