2011-02-06 21 views
6

पर गुरुत्वाकर्षण जोड़ना मैं अपने पहले xna 2d गेम में गुरुत्वाकर्षण अनुकरण करने की कोशिश कर रहा हूं। मैं निम्नलिखितXna एक 2 डी स्प्राइट

 //Used for Jumping 
    double elapsedAirTime = 0.0; 
    double maxAirTime = 8.35; 
    //End Jumping 

तो मैं elapsedAirTime < maxAirTime हालांकि, वहाँ मेरी कोड केवल एक बार और नहीं कई स्प्राइट ऊपर ले जाने के लिए लगता है जहां कुछ मुद्दा है, जबकि एक निश्चित राशि से स्प्राइट ऊपर ले जाने के कोशिश कर रहा हूँ है समय के इस खंड के दौरान समय। यहां मेरे "player.cs" वर्ग, या कक्षा की अद्यतन विधि में कोड है।

if (newState.IsKeyDown(Keys.Space)) 
     { 
      if(oldState.IsKeyUp(Keys.Space)) 
      { 
       //if we are standing or jumping then change the velocity 
       if (playerState == PlayerStates.Standing) 
       { 
        playerState = PlayerStates.Jumping; 
        this.position.Y -= (float)(30.0 + ((1.2)*elapsedAirTime)*elapsedAirTime); 
       } 
      } 
     } 
     //if we are jumping give it some time 
     if (playerState == PlayerStates.Jumping) 
     { 
      if ((elapsedAirTime < maxAirTime) && position.Y < 3) 
      { 
       this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime); 
       elapsedAirTime += gameTime.ElapsedGameTime.TotalSeconds; 
      } 
      //otherwise time to fall 
      else 
      { 
       playerState = PlayerStates.Falling; 
      } 

     } 

     //add gravity to falling objects 
     if (playerState == PlayerStates.Falling || playerState == PlayerStates.Standing) 
     { 
      //if we are above the ground 
      if (this.position.Y < windowBot - 110) 
      { 
       //chnage state to falling 
       playerState = PlayerStates.Falling; 
       this.position.Y += 3.0f + ((float)(gameTime.ElapsedGameTime.TotalSeconds)); 
      } 
      else 
      { 
       playerState = PlayerStates.Standing; 
       elapsedAirTime = 0.0f; 
      } 
     } 

किसी भी मदद की बहुत सराहना की है, कृपया और धन्यवाद!

उत्तर

11

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

 
void Update(GameTime gt) 
{ 
    int updateTime = gt.ElapsedGameTime.TotalMilliseconds - oldgt.ElapsedGameTime.TotalMilliseconds; 
    float timeScalar = updateTime/AVG_FRAME_TIME; 
    this.velocity += this.acceleration * timeScalar; 
    this.position += this.velocity; 
    oldgt = gt; 
} 

आप समय का उपयोग करते हैं, इस विधि थोड़ा जटिल है: यहाँ एक उदाहरण अद्यतन तरीका है। आपको ट्रैक रखना होगा कि अपडेट कितना समय लेता है, फिर इसे उस समय तक विभाजित करें, जिसकी मात्रा आपको उस वेग को प्राप्त करने के लिए लेनी चाहिए, जिससे आप अपनी वेग को समायोजित कर सकते हैं। समय के बिना, विधि बहुत सरल है:

 
void Update() 
{ 
    this.velocity += this.acceleration; 
    this.position += this.velocity; 
} 

मैं सरल विधि का उपयोग कर जब तक आप वास्तव में समझ कैसे समय काम करता है और यही कारण है कि आप इसे लागू करने की आवश्यकता सुझाव है।

+0

क्यों एक समय की गणना करें और पुराना गेम समय स्टोर करें?यदि इस अद्यतन फ़ंक्शन को प्रत्येक गेम लूप (जैसा होना चाहिए) कहा जाता है, तो gt.ElapsedGameTime पहले से ही आपके लिए भारी भारोत्तोलन करता है। –

+1

टाइमस्कर का उपयोग करने का कारण एक है) यदि आप डिफ़ॉल्ट फ्रेम दर बदलना चाहते हैं, या बी) यदि आपका कंप्यूटर इतना धीमा है कि यह डिफ़ॉल्ट 60 यूपीएस/एफपीएस एक्सएनए के साथ जारी नहीं रह सकता है। किसी भी मामले में, यदि आप लक्ष्य अपडेट दर के पीछे आते हैं तो आपका गेम ऐसा लगता है कि समय के बिना स्कालर कोड है। – Darkhydro

2

यह इस लाइन की तरह दिखता है की गलती है:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime); 

मुझे लगता है कि आप इस अद्यतन करता है कि स्प्राइट स्थिति जल्दी से आप कल्पना, स्प्राइट 10 अद्यतन में स्क्रीन को 330 पिक्सल पर आ जाएगा मिलेगा (यह मानते हुए Game.IsFixedTimeStep == true) जो कि दूसरे रीयलटाइम का 1वां हिस्सा है

यह संभावना है कि यह इतनी तेज़ी से अपडेट हो रहा है कि && position.Y < 3 स्थिति से पहले इसे बढ़ाने के लिए आपको कोई बदलाव नहीं आया है और प्लेयरस्टेट को बदलता है।

ऐसा लगता है कि आप कहने की कोशिश कर रहे हैं - अंतरिक्ष सेकंड होने तक 8.5 सेकंड तक प्रति सेकंड x पिक्सेल की दर से कूदें।

आपको इसकी आवश्यकता क्या है this.position.y -= (float) (30 * gameTime.ElapsedGameTime.TotalSeconds) पर गणना को बदलने के लिए, यह कूद कार्रवाई के लिए एक बहुत ही लाइनर आंदोलन देगा, लेकिन इसका मतलब यह होगा कि स्प्राइट प्रति सेकंड 30 पिक्सल पर कूदता है।

यदि Game.IsFixedTimeStep == true - जो डिफ़ॉल्ट है - अपडेट को प्रति सेकंड 60 बार कहा जाता है तो गेमटाइम। एप्लाइड गेमटाइम कुल सेकेंड लगभग हर 0.1 अपडेट होने जा रहा है। यदि कुछ छोड़ने के लिए अपडेट होता है (उदाहरण के लिए मुद्दों को प्रस्तुत करना) तो अपडेट में देरी हो जाएगी और गेमटाइम होगा। एप्लाइडगेमटाइम समेकन 0.3 हो सकता है (2 अपडेट छोड़ दिए गए हैं) लेकिन फॉर्मुलर अभी भी सही कूद दर का काम करता है।