2009-05-21 24 views
166

2 डी गेम में आइसोमेट्रिक टाइल्स खींचने का सही तरीका क्या है?ड्राइंग आइसोमेट्रिक गेम दुनिया

मैंने संदर्भ पढ़े हैं (जैसे this one) जो सुझाव देते हैं कि टाइल्स को इस तरह से प्रस्तुत किया जाए कि मानचित्र के 2 डी सरणी प्रतिनिधित्व में प्रत्येक कॉलम को ज़िग-ज़ैग करेगा। मुझे कल्पना है कि उन्हें एक हीरे के फैशन में और अधिक खींचा जाना चाहिए, जहां स्क्रीन पर खींचा जाता है, 2 डी सरणी की तरह दिखने के लिए अधिक बारीकी से संबंधित है, बस थोड़ा घुमाया गया है।

क्या किसी भी विधि के फायदे या नुकसान हैं?

उत्तर

470

अद्यतन: नक्शा प्रतिपादन एल्गोरिदम सही, और अधिक चित्रण, प्रारूप बदल दिया।

शायद स्क्रीन पर टाइल्स मानचित्रण के लिए "zig-zag" तकनीक के लिए लाभ में कहा जा सकता है कि टाइल के x और y निर्देशांक ऊर्ध्वाधर और क्षैतिज अक्ष पर कर रहे हैं।

"एक हीरे में आकर्षित" दृष्टिकोण:

एक सममितीय मानचित्र का उपयोग "एक हीरे में ड्राइंग" है, जो मेरा मानना ​​है कि सिर्फ दो से अधिक एक नेस्टेड for -loop का उपयोग करके नक्शा प्रतिपादन के लिए संदर्भित करता ड्राइंग तक इस उदाहरण के रूप में आयामी सरणी,:

tile_map[][] = [[...],...] 

for (cellY = 0; cellY < tile_map.size; cellY++): 
    for (cellX = 0; cellX < tile_map[cellY].size cellX++): 
     draw(
      tile_map[cellX][cellY], 
      screenX = (cellX * tile_width/2) + (cellY * tile_width/2) 
      screenY = (cellY * tile_height/2) - (cellX * tile_height/2) 
     ) 

लाभ:

लाभ दृष्टिकोण करने के लिए है यह है कि एक साधारण नेस्टेड for - काफी सीधे आगे तर्क के साथ लूप जो सभी टाइल्स में लगातार काम करता है।

नुकसान: कि दृष्टिकोण को

एक नकारात्मक पक्ष यह है कि नक्शे पर टाइल्स की x और y निर्देशांक विकर्ण लाइनों में वृद्धि होगी, इसे और अधिक मुश्किल बना सकता है जो नेत्रहीन स्क्रीन पर स्थान मैप करने के लिए है एक सरणी के रूप में प्रतिनिधित्व नक्शा करने के लिए:

Image of tile map

हालांकि, वहाँ ऊपर के उदाहरण कोड को लागू करने के लिए एक ख़तरा होने जा रहा है - प्रतिपादन आदेश टाइल्स का कारण होगा कि कुछ टाइल्स के पीछे होने की अपेक्षा की जाती है सामने टाइल्स के ऊपर बनाए जा रहे हैं:

Resulting image from incorrect rendering order

इस समस्या में संशोधन करने के लिए, आंतरिक for -loop के आदेश वापस ले लिया जाना चाहिए - उच्चतम मूल्य से शुरू , और कम मूल्य की ओर प्रतिपादन:

tile_map[][] = [[...],...] 

for (i = 0; i < tile_map.size; i++): 
    for (j = tile_map[i].size; j >= 0; j--): // Changed loop condition here. 
     draw(
      tile_map[i][j], 
      x = (j * tile_width/2) + (i * tile_width/2) 
      y = (i * tile_height/2) - (j * tile_height/2) 
     ) 
ऊपर फिक्स के साथ

, नक्शे का प्रतिपादन सही किया जाना चाहिए:

Resulting image from correct rendering order

"zig-zag" दृष्टिकोण:

लाभ:

शायद "zig-zag" दृष्टिकोण का लाभ यह है कि प्रदान की गई नक्शा एक छोटे से अधिक खड़ी कॉम्पैक्ट प्रतीत हो सकता है है "हीरा" दृष्टिकोण:

Zig-zag approach to rendering seems compact

नुकसान:

टेढ़े-मेढ़ी तकनीक को लागू करने की कोशिश कर रहा से, नुकसान हो सकता है कि यह एक छोटा सा कठिन है प्रतिपादन कोड लिखने के लिए है, क्योंकि यह एक सरणी में प्रत्येक तत्व पर एक नेस्टेड for -loop के रूप में सरल रूप में नहीं लिखा जा सकता है:

Coordinates on a zig-zag order rendering

नोट:: चित्र शामिल

tile_map[][] = [[...],...] 

for (i = 0; i < tile_map.size; i++): 
    if i is odd: 
     offset_x = tile_width/2 
    else: 
     offset_x = 0 

    for (j = 0; j < tile_map[i].size; j++): 
     draw(
      tile_map[i][j], 
      x = (j * tile_width) + offset_x, 
      y = i * tile_height/2 
     ) 

इसके अलावा, यह प्रतिपादन आदेश के कंपित प्रकृति के कारण एक छोटा सा मुश्किल यह पता लगाने की एक टाइल का समन्वय करने की कोशिश करना हो सकता है इस मै रों जवाब है, प्रस्तुत टाइल प्रतिपादन कोड का एक जावा कार्यान्वयन के साथ बनाए गए थे नक्शे के रूप में निम्नलिखित int सरणी के साथ:

tileMap = new int[][] { 
    {0, 1, 2, 3}, 
    {3, 2, 1, 0}, 
    {0, 0, 1, 1}, 
    {2, 2, 3, 3} 
}; 

टाइल चित्र हैं:

  • tileImage[0] -> एक बॉक्स के अंदर के साथ एक बॉक्स।
  • tileImage[1] -> एक काला बॉक्स।
  • tileImage[2] -> एक सफेद बॉक्स।
  • tileImage[3] -> इसमें एक लंबा ग्रे ऑब्जेक्ट वाला एक बॉक्स।

टाइल चौड़ाई पर एक नोट और हाइट्स

चर tile_width और tile_height जो ऊपर कोड उदाहरण में उपयोग किया जाता चौड़ाई और छवि टाइल का प्रतिनिधित्व करने में जमीन टाइल की ऊंचाई का संदर्भ लें:

Image showing the tile width and height

छवि के आयामों का उपयोग करना काम करेंगे, जब तक छवि आयाम और टाइल आयाम मैच के रूप में। अन्यथा, टाइल मानचित्र को टाइल्स के बीच अंतराल के साथ प्रस्तुत किया जा सकता है।

+124

आपने चित्रों को भी खींचा। यह प्रयास है। – zaratustra

+0

चीयर्स कोबर्ड। मैं वर्तमान खेल के लिए हीरा दृष्टिकोण का उपयोग कर रहा हूं, मैं विकास कर रहा हूं और यह एक इलाज कर रहा है। एक बार फिर धन्यवाद। –

+0

चीजों को सुनने के लिए खुशी हुई है :) शुभकामनाएँ! – coobird

10

किसी भी तरह से काम पूरा हो जाता है। मुझे लगता है कि वक्र द्वारा आप कुछ इस तरह का मतलब:

.. .. 01 .. .. 
    .. 06 02 .. 
.. 11 07 03 .. 
    16 12 08 04 
21 17 13 09 05 
    22 18 14 10 
.. 23 19 15 .. 
    .. 24 20 .. 
.. .. 25 .. .. 

(संख्या प्रतिपादन के आदेश हैं) और हीरे से आपका आशय:

.. .. .. .. .. 
    01 02 03 04 
.. 05 06 07 .. 
    08 09 10 11 
.. 12 13 14 .. 
    15 16 17 18 
.. 19 20 21 .. 
    22 23 24 25 
.. .. .. .. .. 

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

+14

मैं वास्तव में आसपास के दूसरे तरीके का मतलब था। हीरा आकार (जो नक्शा चिकनी के किनारों को छोड़ देता है) और ज़िग-ज़ैग विधि, किनारों को तेज कर देता है –

1

आप कुछ टाइल्स है कि अपने हीरे की सीमा से अधिक है, तो मैं गहराई क्रम में ड्राइंग की सलाह देते हैं:

...1... 
..234.. 
.56789. 
..abc.. 
...d... 
0

Coobird के जवाब सही, पूरा एक है। हालांकि, मैंने अपने ऐप (आईओएस/ऑब्जेक्टिव-सी) में काम करने वाले कोड बनाने के लिए किसी अन्य साइट से उन लोगों के साथ अपने संकेत जोड़े, जिन्हें मैं यहां आने वाले किसी भी व्यक्ति के साथ साझा करना चाहता था। कृपया, अगर आप इस उत्तर को पसंद/वोट देते हैं, तो मूल के लिए भी ऐसा ही करें; मैंने जो किया वह "दिग्गजों के कंधों पर खड़ा था।"

सॉर्ट-ऑर्डर के लिए, मेरी तकनीक एक संशोधित चित्रकार के एल्गोरिदम है: प्रत्येक ऑब्जेक्ट में (ए) आधार की ऊंचाई (मैं "स्तर" कहता हूं) और (बी) "बेस" के लिए एक्स/वाई) छवि के "पैर" (उदाहरण: अवतार का आधार उसके पैरों पर है; पेड़ का आधार इसकी जड़ों पर है; हवाई जहाज का आधार केंद्र-छवि है, आदि) तो मैं बस निम्नतम स्तर तक निम्नतम क्रमबद्ध करता हूं, फिर सबसे कम (उच्चतम स्क्रीन) उच्चतम बेस-वाई तक, फिर सबसे कम (बाएं-सबसे) उच्चतम बेस-एक्स तक। यह टाइल को जिस तरह से उम्मीद करता है उसे प्रस्तुत करता है।

कोड टाइल (सेल) को स्क्रीन (बिंदु) कन्वर्ट करने के लिए और वापस: जब आप अन्तर्विभाजक/दो या अधिक अन्य टाइल्स फैले कुछ टाइल/स्प्राइट आकर्षित जरूरत

typedef struct ASIntCell { // like CGPoint, but with int-s vice float-s 
    int x; 
    int y; 
} ASIntCell; 

// Cell-math helper here: 
//  http://gamedevelopment.tutsplus.com/tutorials/creating-isometric-worlds-a-primer-for-game-developers--gamedev-6511 
// Although we had to rotate the coordinates because... 
// X increases NE (not SE) 
// Y increases SE (not SW) 
+ (ASIntCell) cellForPoint: (CGPoint) point 
{ 
    const float halfHeight = rfcRowHeight/2.; 

    ASIntCell cell; 
    cell.x = ((point.x/rfcColWidth) - ((point.y - halfHeight)/rfcRowHeight)); 
    cell.y = ((point.x/rfcColWidth) + ((point.y + halfHeight)/rfcRowHeight)); 

    return cell; 
} 


// Cell-math helper here: 
//  http://stackoverflow.com/questions/892811/drawing-isometric-game-worlds/893063 
// X increases NE, 
// Y increases SE 
+ (CGPoint) centerForCell: (ASIntCell) cell 
{ 
    CGPoint result; 

    result.x = (cell.x * rfcColWidth/2) + (cell.y * rfcColWidth/2); 
    result.y = (cell.y * rfcRowHeight/2) - (cell.x * rfcRowHeight/2); 

    return result; 
} 
0

वास्तविक समस्या है।

समस्या के व्यक्तिगत एनालिसिस के 2 (कठिन) महीनों के बाद मैंने अंततः अपने नए कोकोस 2 डी-जेएस गेम के लिए "सही रेंडर ड्राइंग" पाया और कार्यान्वित किया। समाधान प्रत्येक टाइल (अतिसंवेदनशील) के लिए मानचित्रण में होता है, जो sprites "सामने, पीछे, ऊपर और पीछे" होते हैं। ऐसा करने के बाद आप उन्हें "रिकर्सिव लॉजिक" के बाद आकर्षित कर सकते हैं।

संबंधित मुद्दे