ब्लास्टिंग की गति बढ़ाएं?


9

मैं PyGame में 2d साइडक्रॉलर पर काम कर रहा हूं। प्रत्येक नक्शे के लिए हम एक बनावट का उपयोग करते हैं (यह बनावट का वास्तविक आकार है):

नक्शा बनावट

फिर हम इस कोड के साथ छवि लोड करते हैं:

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

जैसा कि आप देख सकते हैं, वास्तविक मानचित्र बनावट बनाने के लिए बनावट 6 बार फूल जाती है। औसतन यह बनावट लगभग 4500x800 है। इस बनावट को स्क्रीन पर हर फ्रेम पर ब्लिंच करना होता है , क्योंकि पूरी स्क्रीन गंदी होती है (साइड स्क्रॉलिंग के लिए धन्यवाद)। हम इस कोड का उपयोग करते हैं:

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

और यह काम करता है। समस्या यह है कि यह काफी धीमा है: मुझे कम-सभ्य पीसी पर 40 एमपीएस का अल्पांश मिलता है, और यह वास्तविक एआई / वस्तुओं के बिना चल रहा है, जबकि हम 60 एफपीएस के लिए लक्ष्य कर रहे हैं। हम इसे कैसे गति दे सकते हैं?


ध्यान दें कि उपरोक्त कोड को स्वच्छता और संदर्भ से बाहर ले जाया गया है। पूर्ण कोड यहां पाया जा सकता है: https://github.com/nightcracker/PyGG2

और अंतिम लेकिन कम से कम नहीं, जबकि ऊपर की छवि 8-बिट की तरह दिख सकती है, खेल में ऐसे तत्व हैं जिनके लिए अधिक बिट-डेप्थ की आवश्यकता होती है।


प्रति बनावट में एक साइज़ आकार में विभाजित करें, प्रति ब्लॉक 1024 चौड़ा कहें, और एक समय में प्रासंगिक दो को ब्लिट करें।
जरी कोमप्पा

@JariKomppa: इसकी कोशिश की गई है, इसका ब्लिटिंग पर कोई असर नहीं है (pygame स्मार्ट है, केवल ब्लिट को ही मैं इसे बताती हूं), केवल मेमोरी यूज़।
orlp

आप ... pygame (trollface.jpg) का उपयोग नहीं कर सके .... jkjk, इस मामले में मैं अनुमान लगा रहा हूं कि आपकी मंदी जहां नहीं हो रही है, क्या आपने इसे बड़े पैमाने पर परीक्षण किया है?
ultifinitus

@ कुलीनता: हाँ, मैंने इसे cProfile के साथ प्रोफाइल किया है।
orlp

यदि आप इसे वास्तविक रिज़ॉल्यूशन पर प्रदर्शित करते हैं तो गति अंतर क्या है? क्या होगा यदि आप बड़ी छवि बनाते हैं?
अल्टिफिनिटस 15

जवाबों:


7

मुझे ब्लिटिंग पिक्सेल्स से संबंधित कुछ सामान्य तुलनात्मक आशाओं को एक सतह (मेरे अनुभव से) पर सूचीबद्ध करने दें।

1) आमतौर पर पैलेट इमेज (अनुक्रमित चित्र) जब ब्लिंज किए जाते हैं, तो एक अतिरिक्त स्तर पर पुनर्निर्देशन (रंग प्राप्त करने के लिए) के तहत होगा। सही रंग की छवियों की तुलना में ब्लिटिंग के समय वे धीमे होंगे।

2) ट्रू कलर पिक्सेल डेटा (मान लें कि अल्फा - Say24 बिट डेटा के साथ) को बहुत तेज़ी से धुंधला किया जा सकता है क्योंकि हम डिवाइस फ्रेम बफर पर छवि के प्रत्येक स्कैनलाइन (यदि हम छवि के एक हिस्से की नकल कर रहे हैं) के लिए एक मेम्पी कर सकते हैं। .यदि डेटा को ब्लिंक किया जाना है, तो एक पूर्ण छवि है, तो हम सीधे पूरे डेटा को याद कर सकते हैं जो बहुत तेज है!

3) अल्फा पिक्सेल डेटा को नष्ट करना सबसे महंगा होगा क्योंकि इसमें प्रत्येक घटक परिणाम की गणना शामिल होगी और हमें इसे फिर से RGB डेटा में पैक करने की आवश्यकता है। सरल शब्दों में अंतिम रंग प्राप्त करने के लिए प्रत्येक पिक्सेल के लिए अधिक संचालन!

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.

मैंने पहले pyGame पर काम नहीं किया है। लेकिन, इसका एक संक्षिप्त कोड पर एक त्वरित नज़र, मुझे यह मानने के लिए प्रेरित करता है कि यह हुड के नीचे 'sdl' ब्लिट फ़ंक्शन का उपयोग कर रहा है। आमतौर पर Sdl ब्लिट बहुत तेज़ और अनुकूलित होगा, इसलिए उपरोक्त बिंदुओं और प्रोफ़ाइल को एक बार फिर से न बनाएं! सौभाग्य!

* अद्यतन: * रंग कुंजी सेट करना एक अतिरिक्त जांच को जोड़ने के लिए है जब प्रत्येक पिक्सेल को सतह पर रखा जाता है। कुछ इस तरह से -

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

         }

इसलिए, यदि आप देखते हैं, तो हम सीमित रूप से मेमेकपी का उपयोग करने के लिए सीमित नहीं हैं क्योंकि हमें प्रत्येक पिक्सेल की रंग वैधता की जांच करने की आवश्यकता है!


ठीक है, जैसा कि यह set_colorkeyनक्शा बनावट पर फिसलने के लिए कॉल करता है , यह एक (महंगा) अल्फा चैनल देता है। एक convertनिश्चित कि, और अब मैं इस बकवास पीसी पर स्थिर 150 एफपीएस चला रहा हूं। धन्यवाद!
orlp 20

हे रंग कुंजी से संबंधित को संपादित करेगा यहां तक ​​कि कुछ जानकारी जोड़ना भूल गया: डी
अय्यप्पा

5

sprite.convert() आपको लगता है कि यह क्या करता है नहीं करता है।

sprite = sprite.convert() आपको क्या चाहिए


वाह, मैं sprite = sprite.convert()असली कोड में है :)
orlp 19

अहा अच्छा। :) उस मामले में, मेरे पास आपको pygg के बजाय pyglet का उपयोग करने पर विचार करने के अलावा, या सीधे pyOpenGL का उपयोग करने पर विचार करने के लिए बहुत कुछ नहीं है, अगर आप OpenGL के साथ सहज हैं।
काइलोटन

@ किलोटन: अच्छा कैच मेट! मैंने इसकी जाँच नहीं की है :)
अयप्पा

या, और भी बेहतर:sprite = pygame.image.load("Maps/MapTesting.png").convert()
MestreLion
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.