2 डी टाइल वाले गेम में दृष्टि क्षेत्र की गणना जल्दी से कैसे करें?


24

मेरे पास टाइल्स का एक मैट्रिक्स है, उस टाइल में से कुछ पर ऑब्जेक्ट्स हैं। मैं गणना करना चाहता हूं कि कौन सी टाइलें खिलाड़ी को दिखाई दे रही हैं, और जो नहीं हैं, और मुझे इसे काफी कुशलता से करने की आवश्यकता है (इसलिए यह एक बड़े मेट्रिसेस (100x100) और बहुत सी वस्तुओं के होते हुए भी काफी तेजी से गणना करेगा)।

मैंने ब्रेसेनहैम की रेखा एल्गोरिथ्म के साथ इसे करने की कोशिश की , लेकिन यह धीमा था। इसके अलावा, इसने मुझे कुछ त्रुटियां दीं:

----XXX-        ----X**-     ----XXX-
-@------        -@------     -@------
----XXX-        ----X**-     ----XXX-
(raw version)   (Besenham)   (correct, since tunnel walls are 
                              still visible at distance)

(@ is the player, X is obstacle, * is invisible, - is visible)

मुझे यकीन है कि यह किया जा सकता है - आखिरकार, हमारे पास NetHack, Zangband है, और वे सभी किसी न किसी तरह इस समस्या से निपटते हैं :)

आप इसके लिए कौन सा एल्गोरिदम सुझा सकते हैं?


अपनी आवश्यकताओं के लिए, मैं इस तरह से दिखाई देता हूं : टाइल तब दिखाई देती है जब टाइल का कम से कम एक हिस्सा (जैसे कोने) को एक सीधी रेखा के साथ खिलाड़ी टाइल के केंद्र से जोड़ा जा सकता है जो किसी भी बाधा को पार नहीं करता है।


1
वूप्स, मेरी गलती, नेटहैक लाइन-ऑफ-
— व्यू के

कुछ पुराने विचारों को fadden.com/tech/fast-los.html पर पाया जा सकता है , हालांकि यह उन दिनों में वापस आता है जब सीपीयू काफी धीमी गति से चल रहे थे और फ्लोटिंग पॉइंट कंप्यूटेशन कुछ बेहतरीन थे।
— Fadden

जवाबों:


10

दृश्यमान की आपकी परिभाषा निम्नलिखित है:

टाइल दिखाई देती है जब टाइल का कम से कम एक हिस्सा (जैसे कोने) को एक सीधी रेखा के साथ खिलाड़ी टाइल के केंद्र से जोड़ा जा सकता है जो किसी भी बाधा को पार नहीं करता है

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

  1. एल्गोरिथ्म देने के लिए आप जिस सटीकता के स्तर को निर्दिष्ट करना चाहते हैं। यह आपके द्वारा ट्रेस की जा रही किरणों की संख्या होगी।
  2. प्रत्येक किरण के बीच कितने डिग्री घूमने के लिए चुने गए सटीक द्वारा पूर्ण 360 डिग्री सर्कल को विभाजित करें।
  3. 0 डिग्री पर शुरू करना और चरण 2 में निर्धारित राशि द्वारा वृद्धि, खिलाड़ी टाइल के केंद्र में उत्पत्ति के साथ एक किरण बनाना, और वर्तमान कोण द्वारा निर्धारित दिशा।
  4. खिलाड़ी टाइल से शुरू होने वाली प्रत्येक किरण के लिए, किरण की दिशा में तब तक चलें जब तक कि आप एक बाधा टाइल न मार दें। उस टाइल को दृश्यमान टाइल सूची में जोड़ें और अगली किरण पर आगे बढ़ें। कोई टक्कर न मिलने की स्थिति में आप "हार मानने" के लिए अधिकतम दूरी जोड़ना चाहते हैं।

यहाँ एक चित्र दिखाया गया है जिसमें 3 उदाहरण किरणें हैं। गहरे रंग की टाइलें प्रत्येक किरण का "परिणाम" होती हैं, यानी जहां टक्कर हुई। आपको इसे सर्कल के चारों ओर दोहराना होगा:

यहाँ छवि विवरण दर्ज करें

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

संपादित करें

एल्गोरिथ्म के प्रतिच्छेदन बिट को लागू करने में मदद करने के लिए, विशेष रूप से चरण 3 और चरण 4 में, रेकास्टिंग पर निम्नलिखित ट्यूटोरियल की जाँच करें:

http://www.permadi.com/tutorial/raycast/rayc7.html


क्या मुझे प्रत्येक किरण के साथ एक निश्चित दूरी (जैसे, 0.3 अंक) पर "चलना" चाहिए या क्या मुझे प्रत्येक किरण पर बेसेनहैम के एल्गोरिथ्म जैसा कुछ चलाने की आवश्यकता है?
— रोगोप

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

1
एल्गोरिथ्म अच्छा है, लेकिन इसे लंबी 1-टाइल-चौड़ी सुरंगों के साथ बड़ी मात्रा में किरणों की आवश्यकता होती है।
— होलीब्लैककैट

@HolyBlackCat - यह केवल तभी होगा जब आप सभी दिशाओं में कोणों पर भी किरणें भेजेंगे। लेकिन आप उन सभी किरणों को भेजने से बच सकते हैं और केवल उन्हें अपने दृश्य में पंक्ति के अंत में फेंक सकते हैं। यहाँ एक अच्छी व्याख्या है: redblobgames.com/articles/visibility
— Rogach

8

मैं बल्कि छाया की किरणों को दृष्टि की किरणों की रेखा के स्थान पर डालना चाहता था।

मान लें कि यह आपका दृश्य क्षेत्र है (संभावित रूप से दृश्यमान क्षेत्र)

######################
#####.............####
###................###
##..................##
#....................#
#....................#
#..........@.........#
#....................#
#....................#
##..................##
###................###
#####.............####
######################

# ब्लॉक दिखाई नहीं दे रहे हैं जबकि। दिखाई दे रहे हैं

चलो कुछ बाधा डालते हैं X:

######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXXX...........#
##..................##
###....X...........###
#####.............####
######################

आपके पास एक्स की एक सूची है जो दृश्य क्षेत्र के भीतर है तो आप प्रत्येक टाइल के रूप में छिपी हुई है, जो इस बाधा के पीछे है: जब कोई बाधा छिपी हुई है, तो आप इसे सूची से हटा देते हैं।

######################
#####.............####
###................###
##.....X.....XXX....##
#......X.......X.....#
#...X.XX.............#
#...X......@.........#
#...X..........X.....#
#...XXXXX*...........#
##......##..........##
###....*#..........###
#####.###.........####
######################

ऊपर दिए गए उदाहरण में आप नीचे की दीवार के दाईं ओर डाली गई छाया को देख सकते हैं और यह छाया किस तरह से आपके द्वारा जाँच की जाने वाली बाधा की सूची से छिपी हुई बाधा को हटाती है (X को जांचना है? * Check)।

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

आप एक बार में Xs के ब्लॉक को जांचने के लिए "नेवल बैटल" अल्गोरिदम का एक प्रकार का उपयोग कर सकते हैं (मूल रूप से एक adiacent X की तलाश में है जो एक दिशा में है जो छाया शंकु को व्यापक बना सकता है)

[संपादित करें]

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

रे निर्देशांक की गणना बाधा टाइल के चारों ओर एक सरल अंतरिक्ष विभाजन का उपयोग करके की जा सकती है:

अंतरिक्ष विभाजन उदाहरण

प्रत्येक आयताकार क्षेत्र में एक विकल्प का गठन किया जाता है कि टाइल के कोने को छाया कोन किनारे के रूप में लिया जाना चाहिए।

इस तर्क को कई आसन्न टाइलों को जोड़ने के लिए आगे धकेला जा सकता है और उन्हें एक व्यापक शंकु का पालन करने के लिए दिया जाता है।

पहला कदम यह सुनिश्चित करना है कि कोई बाधा पर्यवेक्षक दिशा की ओर नहीं है, उस स्थिति में इसके बजाय निकटतम बाधा माना जाता है:

निकटतम बाधा चुनें

यदि पीली टाइल एक बाधा है जो टाइल नई लाल टाइल बन जाती है।

अब ऊपरी शंकु किनारे पर विचार करने दें:

उम्मीदवार टाइल

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

हरे रंग की टाइल केवल एक उम्मीदवार है यदि पर्यवेक्षक नारंगी रेखा के ऊपर है जो निम्नानुसार है:

विस्तारित जाँच

वही दूसरी किरण के लिए और लाल बाधा के बारे में पर्यवेक्षक के अन्य पदों के लिए खड़ा है।

अंतर्निहित विचार प्रत्येक शंकु कास्टिंग के लिए जितना संभव हो उतना क्षेत्र को कवर करना है और चेक करने के लिए बाधाओं की सूची जितनी जल्दी हो सके छोटा करना है।


दिलचस्प दृष्टिकोण और शायद इसकी घटिया प्रकृति के कारण एक बेहतर विचार है। इसे पढ़ने के बाद मैं शायद इसे इस तरह से भी लागू करूँगा।
— डेविड गाविया

मैं इस तरह की स्थितियों में समस्याओं का पूर्वाभास कर सकता हूं । पीले रंग में खिलाड़ी, नीले और बैंगनी में बाधाएं। खिलाड़ी को बैंगनी बाधा (हरे रंग की किरण दिखाता है) देखने में सक्षम होना चाहिए । लेकिन नीली बाधा से गुजरने वाली लाल छाया किरण बैंगनी टाइल को खारिज कर देती है। लेकिन मुझे लगता है कि दृष्टि संस्करण की रेखा में इससे बड़ी समस्याएं होने की संभावना है।
— डेविड गाविया

यह समस्या "छिपी" की परिभाषा से आती है: जब एक किरण एक टाइल को काटती है तो यह (लगभग) कभी भी इसे पूरी तरह से कवर नहीं करेगी। लाइन सेगमेंट को रेंडर करने के दौरान अलियासिंग के साथ एक ही समस्या हल हो जाती है। व्यक्तिगत रूप से मुझे लगता है कि एक टाइल छिपी हुई है जब इसके प्रमुख भाग को कवर किया गया है, कोई इसे परिभाषित कर सकता है जो पूरी तरह से छिपा हुआ है, आप पा सकते हैं कि क्या यह एक पक्ष को उजागर करता है जो संभवतः छाया शंकु को व्यापक बना सकता है ... वैसे भी, आप कर सकते हैं केवल उन ब्लॉकों को वितरित करें जो पूरी तरह से कवर किए गए हैं।
— FxIII

@DavidGouveia - कौन सी बड़ी समस्याएं?
— रोजेक

@ दाविदगाविया - मैंने पहले ही छाया "शंकु" के साथ दृष्टिकोण की कोशिश की, और यह बहुत अक्षम था। दृश्यता किरणों की सटीकता के लिए - ~ 5500 किरणें प्रत्येक दिशा में दीवार को देखने के लिए पर्याप्त हैं यदि आप सीधे उसके पास खड़े हैं, और जितनी दूरी पर बस एक एकल टाइल दिखाई दे रही है वह कहीं अधिक है। और के रूप में बड़ी दूरी पर कुछ टाइलें गायब करने के लिए - ठीक है, हर कोई प्रीफेक्ट दृष्टि नहीं है, एह?
— रोगच

8

जिस समस्या को आप हल करने की कोशिश कर रहे हैं उसे कभी-कभी फील्ड ऑफ व्यू, शॉर्ट के लिए FOV कहा जाता है। जैसा कि आपने उदाहरण के तौर पर roguelikes का उल्लेख किया है, आपको इस बात पर एक नज़र डालनी चाहिए कि RogueBasin विकी का विषय के बारे में क्या कहना है (इसमें कार्यान्वयन के लिए लिंक भी है): http://www.roguebasin.com/index.php?title/Field_of_Vision

अलग-अलग पेशेवरों और विपक्षों के साथ कुछ अलग एल्गोरिदम हैं - एक बहुत ही आसान तुलना भी उपलब्ध है RogueBasin: http://www.roguebasin.com/index.php?title=Comparative_study_of_field_of_view_algorithms_for_2D_grid_based_worlds


वास्तव में अच्छा और पूरा सारांश!
— दुष्ट

वह वेब साइट एक महान संसाधन है, उस लिंक को साझा करने के लिए धन्यवाद। इसमें ए * पाथफाइंडिंग कैसे काम करता है का एक आश्चर्यजनक रूप से समझने योग्य विवरण भी शामिल है :-)
— उलटी गवाह

उत्तर में लिंक अब साइट के होम पेज पर जाता है - roguebasin.com/index.php?title=Category:FOV एक उचित मेल प्रतीत होता है।
— फादन


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.