2011-09-07 13 views
6

निर्धारित करना मैं वर्तमान में सी # & एक्सएनए का उपयोग कर टावर रक्षा गेम बना रहा हूं। खेल थोड़ी देर के लिए ठीक और सुचारू रूप से चलता है लेकिन पर्याप्त समय के लिए खेलने के बाद (पर्याप्त दुश्मन/टावर्स/गोलियां पैदा होने के बाद) गेम तेजी से धीमा लगता है। यहां तक ​​कि जब सभी उदाहरणों को मंजूरी दे दी जाती है तब भी अंतराल बनी रहती है।एक्सएनए गेम लैग

पहले मैंने सोचा कि इसे कचरा संग्रह (और शायद यह करता है) के साथ करना पड़ सकता है लेकिन इसका परीक्षण करने के लिए मैंने किसी ऑब्जेक्ट को इकट्ठा करने के दौरान विनाशकों को मुद्रित करने के लिए लिखा और सब कुछ ठीक दिखता है (सभी वस्तुओं को एकत्र किया जाता है)। तो मुझे उत्सुकता है अगर किसी को XNA में अंतराल और इसके संभावित कारणों से कोई अनुभव है?

संपादित करें: इस पीसी

+0

सुझाव: एक बेहतर (कुल) प्रश्न हो सकता है -> क्या मैं निर्धारित करने के लिए जहां अंतराल हो रहा है कर सकते हैं? ऐसा लगता है कि यह कई अलग-अलग चीजों के कारण हो सकता है, हमें अंतराल की समस्या की जड़ निर्धारित करने के लिए अपने कोड का बहुत कुछ देखना होगा – jadarnel27

+0

बस देखने के लिए बहुत अधिक कोड है। मैं सैद्धांतिक समाधान या संभावित कारणों के लिए और अधिक पूछ रहा हूं। वर्तमान में इसमें कोई नेटवर्किंग शामिल नहीं है, इसलिए कोई मुद्दा नहीं होना चाहिए। – Johannes

+1

एक चीज जो मैं सुझाऊंगा वह प्रिंट करना है (एक डीबग लॉग फ़ाइल या कुछ करने के लिए) एक टाइमस्टैम्प जब आप प्रवेश करते हैं और संदेह के अपने बड़े सबराउटिन/क्षेत्रों से बाहर निकलें। इस तरह आप देख सकते हैं कि आप उस समय कहां खो रहे हैं, और – jadarnel27

उत्तर

1

वहाँ दो चीजें हैं जो मैं प्रदर्शन की जाँच करने के लिए इस्तेमाल किया है के लिए है।

1) ऐप हब में Performance utility है जिसका उपयोग आप यह निर्धारित करने में सहायता के लिए कर सकते हैं कि आप क्या सुधार कर सकते हैं।

2) यह अब थोड़ा पुराना है, लेकिन for the Xbox 360 this document helped me a lot है।

अद्यतन: मैं भी this Gamefest 2010 presentation भूल गया। यह कुछ चीजों पर भी चला जाता है।

0

क्या खेल लूप का समय बढ़ गया है? स्टार्टवॉच को शुरुआत में और अपडेट लूप और ड्रा लूप के अंत तक जोड़ें। यदि यह बढ़ रहा है, तो बाहर निकलने का प्रयास करें (स्टॉपवॉच। स्टार्ट() और/या स्टॉपवॉच करें। स्टॉप()) जब तक कि आपको धीमा न हो जाए। यदि यह नहीं बढ़ रहा है, तो यह किसी और चीज के कारण होता है। कोड के लिए इस लाइन को जोड़ने के लिए

प्रयास करें:

SpriteBatch.DrawInt64(Font, GC.GetTotalMemory(false)/1000 /* in kilobytes */, 
POSITION, Color.White, 0f); 

(DrawInt64/32 spritebatch को वास्तव में उपयोगी विस्तार है जो आप कचरा पैदा करने के बिना संख्या आकर्षित करने के लिए अनुमति देता है, यहाँ उपलब्ध है:। http://pastebin.com/pVw66mGy वैकल्पिक रूप से सिर्फ DrawString का उपयोग करें और ।तार())।

प्रत्येक बार प्रदर्शित होने वाली संख्या घट जाती है, कचरा संग्रह चलाया जाता है।

+0

यह निर्धारित करने का एक बेहतर तरीका है कि कचरा संग्रह हो रहा है या नहीं, जीसी.कोलेक्शनकाउंट() का उपयोग करना है। इससे आपको यह देखने की अनुमति मिल जाएगी कि प्रत्येक पीढ़ी को कब एकत्र किया जाता है। जनरेशन 0 संग्रह शायद एक बड़ा सौदा नहीं है; जब प्रदर्शन की बात आती है तो पीढ़ी 1 और 2 संग्रह चिंता का अधिक होता है। –

1

यदि आप चिंतित हैं कि कचरा संग्रह प्रदर्शन को प्रभावित कर रहे हैं, तो आप उपयोग करने के लिए सीखने वाले सर्वोत्तम टूल में से एक CLR Profiler है। यह उपयोगिता आपको अपने कार्यक्रम द्वारा किए गए ढेर आवंटन को प्रोफ़ाइल करने की अनुमति देती है, ताकि आप यह पहचान सकें कि कौन सी विधियां कचरा उत्पन्न कर रही हैं। याद रखें कि बहुत सी गैर-स्पष्ट चीजें ढेर पर आवंटित की जा सकती हैं: समेकित तार, गणना कुंजी, बंद, प्रतिनिधियों इत्यादि के साथ अनुक्रमणित शब्दकोश। यहां तक ​​कि प्रति फ्रेम 60+ फ्रेम प्रति सेकेंड पर प्रति फ्रेम उत्पन्न होने के बाद भी थोड़ा कचरा, जल्दी से जोड़ सकता है सही परिस्थितियों में।

उसने कहा, जो आपने वर्णन किया है वह मुझे कचरा संग्रह के साथ किसी समस्या की तरह नहीं लगता है। जीसी आमतौर पर एक पूर्ण संग्रह के दौरान भी पर्याप्त तेज़ होता है, केवल कुछ फ्रेमों को छोड़ने के कारण - दूसरे शब्दों में, आप हर बार एक मामूली, कष्टप्रद झटका देखते हैं, लेकिन लगातार मंदी नहीं देखते हैं।

(चेतावनी: यह केवल पीसी है, जो अन्य XNA प्लेटफार्मों की तुलना में एक बहुत परिष्कृत जीसी है पर लागू होता है।)

आप अपने कोड के लिए एक प्रोफाइलर संलग्न की पहचान के लिए जो तरीकों सबसे लंबे समय तक ले जा रहे हैं पूरा करने के लिए प्रयास करना चाहिए ; यदि आपकी समस्या जीसी से संबंधित नहीं है, तो यह जानकारीपूर्ण हो सकती है। अतीत में, मैंने EQATEC का उपयोग किया है, हालांकि मुझे उनके कुछ हाल के संस्करणों के साथ समस्याएं आई हैं। आप इसे एकमात्र कोशिश कर सकते हैं, या आप वैकल्पिक रूप से Google पर देख सकते हैं।

0

आप घटनाओं को अनदेखा करने के लिए भूल नहीं रहे हैं? नीचे दिए गए उदाहरण में मैं एक सूची में 4 sprites जोड़ता हूं, प्रत्येक स्प्राइट खेल से एक घटना हुक करता है। मैं फिर एक स्प्राइट हटा देता हूं और घटना को बढ़ाता हूं।

इस स्थिति में सभी 4 sprites अभी भी सक्रिय हैं और उनकी घटना को उठाया गया है क्योंकि गेम में अभी भी उनका संदर्भ है।

सिर्फ एक विचार, यदि आप अपनी गेम ऑब्जेक्ट्स के लिए ईवेंट का उपयोग कर रहे हैं तो आप उन्हें अभी भी चल रहे सभी छोड़ सकते हैं।

class Game 
{ 
    public event EventHandler SomeEvent; 
    List<Sprite> sprites; 

    public Game() 
    { 
    sprites = new List<Sprite>(); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 
    sprites.Add(new Sprite(this)); 

    sprites.RemoveAt(0); 

    EventHandler temp = SomeEvent; 
    if (temp != null) 
    { 
     temp(this, EventArgs.Empty); 
    } 
    } 

    static void Main(string[] args) 
    { 
     Game newProgram = new Game(); 
    } 



    class Sprite 
    { 
     public Sprite(Game gameReference) 
     { 
      gameReference.SomeEvent += new EventHandler(gameReference_SomeEvent); 
     } 

     void gameReference_SomeEvent(object sender, EventArgs e) 
     { 
      Debug.WriteLine("Event"); 
     }  
    } 
संबंधित मुद्दे