सबसे पहले, मुझे पता है कि मेरी ड्राइंग समस्या क्या है, और मुझे इसे हल करने के तरीके के बारे में विभिन्न विचार हैं। मैं यहां यह पता लगाने के लिए हूं कि किस फ्रेम को कैसे समायोजित किया जाए ताकि आइसोमेट्रिक "भ्रम" बनाए रखा जाए।
मैं एक 2D, बर्ड-आई व्यू गेम लिख रहा हूं जो अंतरिक्ष में होता है। मैं एक ऐसी दुनिया में आइसोमेट्रिक ग्राफिक्स का उपयोग करने की कोशिश कर रहा हूं, जहां अप नॉर्थ है, पारंपरिक आइसोमेट्रिक गेम्स की तरह खेल की दुनिया का कोई घूर्णन नहीं है (याद रखें, खेल अंतरिक्ष में जगह लेता है, कोई इलाक़ा नहीं)। यहाँ एक उदाहरण दिया गया है जिसे मैं इस्तेमाल करने की कोशिश कर रहा हूं: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.png 64 बार घुमाया गया, इसके बारे में 35 डिग्री के व्यूइंग कोण के साथ खुद का ऊर्ध्वाधर अक्ष है (उर्फ, आईएसओ)। छवि उत्पन्न की गई थी, इसलिए इसे बदला जा सकता है।
स्पष्टता के लिए, मैंने तय किया है कि उत्तर (ऊपर) 0 डिग्री है, और पूर्व (दाएं) 90 है।
मेरी समस्या यह है कि मेरा स्प्राइट हमेशा ऐसा नहीं दिखता है जैसे यह सामना कर रहा है जहां खेल को लगता है कि यह इस्तेमाल किए गए 3 डी विमानों में अंतर के कारण है। यकीन नहीं होता कि मैं शब्दावली का सही ढंग से उपयोग कर रहा हूं, लेकिन मेरा अंतरिक्ष यान एक विमान पर घुमाया गया था, और दृश्य विमान अपने स्वयं के विमान पर चीजों को घुमाए जाने की उम्मीद कर रहा है। यहाँ समस्या का चित्रण है:
http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectionIssue.png बाईं ओर, मेरे पास साइड व्यू हैं, दाईं ओर मेरे ऊपर-नीचे विचार हैं। शीर्ष पर, मेरे पास दुनिया का अंतरिक्ष जहाज / स्प्राइट शीट दृश्य है। तल पर, मेरे पास स्प्राइट जैसा दिखता है जब इसे स्क्रीन पर खींचा जाता है।
शीर्ष दाईं ओर एक सरलीकृत संस्करण है कि कैसे मेरा स्पेसशिप घुमाया गया था (यहां तक कि प्रत्येक फ्रेम के बीच डिग्री पृथक्करण)। नीचे दाईं ओर वह कोण है जो स्प्राइट जैसा दिखता है , जब स्क्रीन पर एक विशेष कोण खींचा जाता है। समस्या लगभग 45 डिग्री पर स्पष्ट है। यहाँ एक छवि है जो एक "स्क्रीन प्लेन" लाइन के साथ ओवरलैड है जो इस दिशा में इंगित की गई है कि जहाज का सामना करना पड़ रहा है: http://cell.stat-life.com/images/stories/AsteroidOutpost/SpaceshiphipRedLine.png लाल रेखा को हमेशा जहाज के समान सटीक दिशा में इंगित किया जाना चाहिए , लेकिन जैसा कि आप देख सकते हैं, प्रक्षेपण मुद्दा एक समस्या पैदा कर रहा है। मुझे उम्मीद है कि मैं इस मुद्दे का अच्छी तरह से वर्णन कर रहा हूं।
EDIT: लाल रेखा को स्क्रीन प्लेन पर घुमाया जाता है, जबकि अंतरिक्ष जहाज को "शिप प्लेन" पर घुमाया जाता है, इसलिए इसे खींचे जाने पर जहाज के एंगल और स्क्रीन एंगल के बीच बड़ा अंतर होता है। END EDIT
यह अजीब लगता है जब यह जहाज एक लक्ष्य पर एक लेजर बीम की शूटिंग कर रहा है जो एक तरफ से दूर है, जब इसे सीधे आगे की शूटिंग की जानी चाहिए।
तो ... मैं जिन समाधानों के साथ आया हूं वे हैं:
- एक आइसोमेट्रिक दृश्य नकली करने की कोशिश करना बंद करो, बड़ा हो या घर जाओ। मेरी दुनिया को पहले से ही घुमाओ। (पुनश्च: यह मेरी समस्या को ठीक करेगा?)
- मेरी स्प्राइट शीट (किसी तरह) को फ्रेम करें जो "स्क्रीन कोण" का प्रतिनिधित्व करता है कि मॉडल को देखा जाएगा। इसलिए जब मैं 45 डिग्री की छवि मांगता हूं, तो यह वास्तव में ऐसा लगेगा जैसे यह स्क्रीन पर 45 डिग्री का सामना कर रहा है।
- स्प्राइट शीट (किसी तरह) से एक अलग फ्रेम को हथियाने के लिए मेरी स्प्राइट रेंडरिंग प्रणाली को सचेत करें, यह जानते हुए कि "सामान्य" फ्रेम को हथियाना मज़ेदार लगेगा। तो 45 डिग्री के फ्रेम हथियाने के बजाय, यह ... 33 डिग्री फ्रेम (सिर्फ अनुमान लगा) इतना है कि यह हड़पने जाएगा लग रहा है उपयोगकर्ता के लिए सही।
- बस 3 डी का उपयोग करें! यह इतना आसान आदमी है
एक के लिए: आप किस समाधान की सिफारिश करेंगे? मैं 2 की ओर झुक रहा हूं, हालांकि मुझे पता है कि यह गलत है। याद रखें कि स्प्राइट जनरेशन टूल तक मेरी पूरी पहुंच है। विधि 3 मेरी दूसरी पसंद होगी। इन दोनों विधियों को बस यह चाहिए कि मैं अपना वांछित परिणाम प्राप्त करने के लिए कोण पर कुछ गणित लागू करूं। Btw, मैंने एक मजाक के रूप में # 4 को जोड़ा, मैं 3 डी में नहीं जाना चाहता।
दो के लिए: विधियों 2 या 3 का उपयोग करना, मैं इनपुट या आउटपुट कोणों को कैसे समायोजित करूंगा? मैं 3D अनुमानों और 3D मैट्रिसेस (अकेले 2D 2D मैट्रिसेस) के साथ वह सब अच्छा नहीं कर रहा हूँ, और मुझे वांछित परिणाम प्राप्त करने के लिए अन्य किसी भी गणित का उपयोग किया जा सकता है।
यहाँ ज़ोर से सोचना: अगर मैं एक यूनिट वेक्टर का सामना उस दिशा में कर रहा हूँ जो मैं चाहता हूँ कि जहाज स्क्रीन पर (स्क्रीन प्लेन पर) दिखे, तो प्रोजेक्ट करें कि जहाज प्लेन पर है, तो यह पता लगाएँ कि उस अनुमानित लाइन और प्लेन के बीच का कोण क्या है उत्तर है, मेरे पास जहाज के ग्राफिक का कोण होना चाहिए जिसे मैं प्रदर्शित करना चाहता हूं। सही? (# 3 के लिए समाधान?) यार ... मैं यह काम नहीं कर सकता।
संपादित करें:
मुझे पता है कि समस्या स्थैतिक छवियों के साथ कल्पना करना कठिन है, इसलिए मैंने इस मुद्दे को प्रदर्शित करने के लिए अपने स्प्राइट लाइब्रेरी विज़ुअल टेस्टर का अनुपालन किया है: http://cell.stat-life.com/downloads/SpriteLibVisualTest.zip यह XNA 4.0 है। यह एप्लिकेशन है बस स्प्राइट को घुमाना, और इसके केंद्र बिंदु से एक रेखा खींचना कोण पर खेल को लगता है कि जहाज का सामना करना चाहिए।
EDIT 8 सितंबर
मेरी "ज़ोर से सोच" पैराग्राफ से जारी: एक प्रक्षेपण का उपयोग करने के बजाय (क्योंकि यह कठिन लग रहा है) मैं सोच रहा हूं कि मैं एक उत्तर का सामना करना पड़ रहा इकाई वेक्टर (0x, 1y, 0z) ले सकता हूं, इसे कोण पर घुमाने के लिए एक मैट्रिक्स का उपयोग करें। स्प्राइट वास्तव में सामना कर रहा है, फिर एक्स अक्ष के चारों ओर "स्प्राइट प्लेन" के लिए "देखने वाले विमान" से इसे फिर से घुमाएं, फिर ... समतल करें? सदिश (अनिवार्य रूप से यह प्रोजेक्ट) केवल एक्स और वाई (ज़ेड को अनदेखा करते हुए) का उपयोग करके देखने वाले विमान पर वापस। फिर उस नए चपटा वेक्टर का उपयोग करते हुए, मैं इसके कोण को निर्धारित कर सकता हूं और इसका उपयोग कर सकता हूं ... कुछ कुछ। मैं बाद में सोचूंगा।
EDIT 8 सितंबर (2)
मैंने कुछ सफलता के साथ ऊपर से अपने विचार का पालन करने की कोशिश की, याय! तो ... यह देखने के लिए कि यह मेरे स्पेसशिप से सीधे आ रहा है (केवल परीक्षण के उद्देश्य) के लिए एक लाल रेखा प्राप्त करने के लिए , मैंने निम्नलिखित कार्य किया:
Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);
float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));
rotationस्क्रीन एंगल कहां है और adjustedRotationअब स्क्रीन एंगल स्प्राइट प्लेन पर दिखता है। मुझे नहीं पता कि मुझे X के बजाय Y को घुमाने की आवश्यकता क्यों थी, लेकिन यह शायद 3D के साथ कुछ ऐसा है जिसके बारे में मुझे नहीं पता है।
तो, अब मेरे पास जानकारी का एक अतिरिक्त टुकड़ा है, लेकिन मैं इसका उपयोग अधिक उपयुक्त फ्रेम चुनने के लिए कैसे करूं? हो सकता है कि दृश्य विमान से स्प्राइट विमान में घूमने के बजाय, फिर वापस प्रोजेक्ट करते हुए, मुझे इसे दूसरे तरीके से करने की कोशिश करनी चाहिए। यहाँ एक समायोजित लाल रेखा के साथ मेरा स्प्राइट है, लेकिन मैं वास्तव में जो करना चाहता हूं वह मॉडल को समायोजित करना है, न कि रेखा: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLorCorrected.png
EDIT 9 सितंबर
Horay! यह तय हो चुका है! मैं वर्णन करूँगा कि मैंने इसे ठीक करने के लिए क्या किया:
मैंने दुनिया के समन्वय प्रणाली (या फैला हुआ ...?) के द्वारा eBusiness की सलाह और "स्क्वीड" का पालन किया। यह अनिवार्य रूप से # 1 समाधान है, हालांकि मैं इस धारणा के तहत था कि मुझे स्क्रीन समन्वय प्रणाली के संबंध में अपनी विश्व समन्वय प्रणाली को घुमाना होगा। सच नहीं! ऊपर अभी भी + y है, और राइट अभी भी + x है। मैंने अपनी WorldToScreen और ScreenToWorld विधियों को दुनिया और स्क्रीन निर्देशांक के बीच ठीक से परिवर्तित करने के लिए संशोधित किया है। ये विधियाँ इष्टतम नहीं हो सकती हैं, लेकिन यहाँ मेरे कोडबेस में केवल दो विधियाँ हैं जिन्हें बदलना था।
public Vector2 ScreenToWorld(float x, float y)
{
float deltaX = x - (size.Width / 2f);
float deltaY = y - (size.Height / 2f);
deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
deltaY = deltaY * scaleFactor;
return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}
public Vector2 WorldToScreen(float x, float y)
{
float deltaX = x - focusWorldPoint.X;
float deltaY = y - focusWorldPoint.Y;
deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
deltaY = deltaY / scaleFactor;
return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}
वह यह था! उन दो तरीकों को बदलने से बाकी सब प्रभावित हुआ: जो मैं देख रहा था, जहां वस्तुएं खींची गईं, जहां मैं क्लिक कर रहा था, सब कुछ। मेरा अंतरिक्ष यान अब सीधे उस लक्ष्य पर नज़र आ रहा है, जिसकी वह शूटिंग कर रहा है, और सब कुछ घट रहा है। मैं ऑर्थोग्राफिक प्रोजेक्शन के साथ प्रयोग करूंगा, देखें कि क्या यह सब कुछ अधिक वास्तविक लगता है।
