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

यह मार्गदर्शिका एक काम पर केंद्रित है: Mac ऐप में उपयोगकर्ताओं द्वारा ऐप के अपने कार्यक्षेत्र में खींचे जाने वाले, स्मृति में मौजूद कृत्रिम वृत्तों या आयतों के लिए इंटरैक्शन आर्किटेक्चर चुनना। यह निर्णय टकराव के व्यवहार, इनपुट रूटिंग और प्रत्येक आकार की स्थिति को नियंत्रित करने वाले घटक पर निर्भर करता है।

दो आकार मिलने पर क्या होना चाहिए?

“टकराव प्रतिक्रिया” कई अलग-अलग आवश्यकताओं को दर्शा सकती है। ओवरलैप को हाइलाइट करना, अमान्य स्थिति को अस्वीकार करना और दो वस्तुओं को उछालना—इन सबके लिए अलग-अलग तरीके चाहिए। Apple स्पष्ट रूप से SpriteKit के संपर्कों को, जो छूते हुए बॉडी की सूचना देते हैं, टकरावों से अलग बताता है, जो भौतिक प्रतिक्रिया की गणना करके आवेग लागू करते हैं। टकरावों और संपर्कों के बारे में

वांछित व्यवहार व्यावहारिक शुरुआती विकल्प आपकी ज़िम्मेदारी
पॉइंटर से आकार को स्वतंत्र रूप से रखते समय ओवरलैप हाइलाइट करना कस्टम ज्यामिति परीक्षणों वाला Canvas चयन, ओवरलैप का पता लगाना और दृश्य प्रतिक्रिया
आकार को पहली बाधा पर रोकना कस्टम गति-प्रतिबंधों वाला Canvas गति-पथ की जाँच करना और स्वीकार्य स्थिति तय करना
पास के आकारों को धकेलना और उन्हें स्थिर होने या उछलने देना SpriteKit भौतिकी कॉन्फ़िगरेशन और ड्रैग कंट्रोलर
हर आइटम को सामान्य SwiftUI नियंत्रण और जेस्चर देना अलग-अलग SwiftUI दृश्य ऐप-विशिष्ट ओवरलैप या गति नियम

ये दस्तावेज़ित क्षमताओं से निकली आर्किटेक्चर संबंधी सिफ़ारिशें हैं, Apple के प्रदर्शन मानदंड नहीं। कम आकार होने से Canvas अपने-आप बेहतर नहीं हो जाता, और अधिक आकार होने से SpriteKit अपने-आप ज़रूरी नहीं हो जाता। पहले व्यवहार चुनें, फिर प्रतिनिधि आइटमों के साथ कार्यान्वयन का मापन करें।

एक उपयोगी इंटरैक्शन सीमा भी है: पॉइंटर को सटीक रूप से ट्रैक करना और ओवरलैप को पूरी तरह रोकना परस्पर टकरा सकते हैं। यदि पॉइंटर किसी भरी हुई स्थिति से गुज़रता है, तो ऐप को आइटम को ओवरलैप करने देना होगा, पॉइंटर के पीछे रोकना होगा या दूसरे आइटमों को हटाना होगा। रेंडरर चुनने से पहले यह तय करें।

Canvas क्या देता है, और आपको क्या बनाना होगा?

Canvas ग्राफ़िक्स कॉन्टेक्स्ट के ज़रिए तत्काल-मोड ड्रॉइंग देता है। इसके वृत्त, पथ और प्रतीक अलग-अलग इंटरैक्टिव तत्व नहीं बनते। Apple यह भी कहता है कि Canvas अलग-अलग ड्रॉ किए गए तत्वों के लिए एक्सेसिबिलिटी नहीं देता, इसमें दृश्यों के रूप में दिए गए प्रतीक भी शामिल हैं। इसलिए Canvas पर लगाए गए जेस्चर के लिए ऐप लॉजिक चाहिए, जो तय करे कि उपयोगकर्ता ने कौन-सा आइटम चुना है। Canvas

स्पष्ट स्थान-निर्धारण नियमों वाले एडिटर के लिए, आकारों को मॉडल में रखें और ड्रॉइंग को उस मॉडल का दृश्य रूप मानें। हर आइटम में पहचानकर्ता, केंद्र, आयाम और ड्रॉइंग क्रम हो सकता है। Swift की सलाह है कि सामान्य डेटा के लिए डिफ़ॉल्ट रूप से संरचनाएँ इस्तेमाल करें और साझा पहचान या फ़्रेमवर्क इनहेरिटेंस की ज़रूरत होने पर क्लास का उपयोग करें। मान प्रकार का आइटम मॉडल और SpriteKit सीन सबक्लास अलग-अलग काम करते हैं। संरचनाओं और क्लासों के बीच चयन

Canvas ड्रैग इस क्रम में चल सकता है:

  1. जेस्चर शुरू होते ही, शुरुआती पॉइंटर स्थान को आइटमों से ऊपर से नीचे की ड्रॉइंग परतों के उल्टे क्रम में जाँचें और पहला मेल खाने वाला आइटम चुनें।
  2. पूरे जेस्चर के लिए चुने गए पहचानकर्ता और उसका मूल केंद्र बनाए रखें।
  3. हर प्रस्तावित केंद्र की गणना मूल केंद्र और जेस्चर के कुल ट्रांसलेशन को जोड़कर करें।
  4. स्वीकार्य केंद्र पाने के लिए कार्यक्षेत्र की सीमाएँ और टकराव नियम लागू करें।
  5. मॉडल अपडेट करें; Canvas को उसी से फिर से ड्रॉ करने दें।
  6. जेस्चर समाप्त होने पर चयन हटाएँ और बीच में बाधित हुए इंटरैक्शन के लिए सफ़ाई का तरीका तय करें।

कुल और वृद्धिशील गति के बीच का अंतर मायने रखता है। SwiftUI translation को जेस्चर की शुरुआत से हुई गति के रूप में परिभाषित करता है। पहले से अपडेट किए गए केंद्र में हर बार यह कुल मान जोड़ने से गति ज़रूरत से ज़्यादा बढ़ जाती है। हर बार बनाए रखे गए शुरुआती केंद्र का उपयोग करें। SwiftUI जेस्चर मान के ज़रिए startLocation, location और translation उपलब्ध कराता है, और आपको जेस्चर का कॉर्डिनेट स्पेस निर्दिष्ट करने देता है। DragGesture.Value, DragGesture

ड्रैग के दौरान चयन स्थिर रखें। पॉइंटर के हर अपडेट पर शुरुआती चयन प्रक्रिया दोहराने से, पॉइंटर के किसी दूसरे आकार के ऊपर से गुज़रने पर चयनित आइटम बदल सकता है। इसी तरह, पॉइंटर और केंद्र के बीच शुरुआती ऑफ़सेट बनाए रखने से आकार उछलकर अचानक पॉइंटर के नीचे केंद्रित नहीं होता। ये ऐप डिज़ाइन के नियम हैं; Canvas इन्हें अपने-आप लागू नहीं करता।

उदाहरण: ओवरलैप का पता लगाना बनाम गति रोकना

मान लें कि दो उदाहरणात्मक वृत्तों की त्रिज्या 20 पॉइंट है। वृत्त A (100, 100) पर शुरू होता है और स्थिर वृत्त B (200, 100) पर है। उपयोगकर्ता A का केंद्र (190, 100) पर रखना चाहता है। उनके केंद्रों के बीच की दूरी 10 पॉइंट होगी; उनकी त्रिज्याओं का योग 40 है। यह संभावित स्थिति ओवरलैप करती है।

ओवरलैप संकेतक के लिए, इस स्थिति को स्वीकार करें और ड्रॉइंग बदलें। क्षैतिज ड्रैग को रोकने के लिए, पहली स्पर्श स्थिति (160, 100) है: तब केंद्रों के बीच 40 पॉइंट की दूरी होती है। यह गणना मानती है कि B स्थिर रहता है, दोनों वृत्तों का आकार वही रहता है और A क्षैतिज पथ पर चलता है।

अब मान लें कि पॉइंटर का एक अपडेट (260, 100) की स्थिति माँगता है। केवल उस अंतिम स्थिति की जाँच करने पर कोई ओवरलैप नहीं मिलेगा, जबकि गति-पथ B के बीच से गुज़रता है। अवरुद्ध ड्रैग लागू करने के लिए पूरी गति-पथ पर प्रतिच्छेदन की जाँच या बीच के पथ को जाँचने का कोई अन्य स्पष्ट तरीका चाहिए। केवल ओवरलैप करने वाली अंतिम स्थितियों को अस्वीकार करने से “पहली बाधा पर रुकना” लागू नहीं होता।

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

SpriteKit कब बेहतर विकल्प बनता है?

जब टकराव प्रतिक्रिया सिमुलेशन से उभरनी चाहिए, तब SpriteKit आकर्षक विकल्प बनता है। किसी नोड में SKPhysicsBody जोड़ने से गुरुत्वाकर्षण, घर्षण और टकरावों की गणना संभव होती है; फिर सिमुलेशन नोड की स्थिति और अभिविन्यास अपडेट करता है। यह वस्तुओं के लिए आयतन बॉडी और सीमाओं के लिए किनारा बॉडी का समर्थन करता है। SKPhysicsBody

पहले प्रोटोटाइप के लिए, दो अलग-अलग वृत्तों और आयताकार कार्यक्षेत्र की सीमा से शुरुआत करें। वृत्तों को समान वृत्ताकार बॉडी दें, टेबल जैसी सतह वाले कार्यक्षेत्र के लिए गुरुत्वाकर्षण बंद करें और तय करें कि घूर्णन से इंटरैक्शन को कोई लाभ होता है या नहीं। घर्षण, प्रत्यास्थता और डैम्पिंग को सोच-समझकर कॉन्फ़िगर करें, डिफ़ॉल्ट मानों पर निर्भर न रहें। ये गुण भौतिक व्यवहार के अलग-अलग पहलुओं को तय करते हैं। SKPhysicsBody

SwiftUI सीधे SpriteView के ज़रिए सीन होस्ट कर सकता है, जिसे Apple SpriteKit सीन रेंडर करने वाले SwiftUI दृश्य के रूप में दस्तावेज़ित करता है। दस्तावेज़ों के अनुसार Mac पर इसकी उपलब्धता macOS 11 से शुरू होती है; Canvas macOS 12 से उपलब्ध है। इसलिए डिप्लॉयमेंट टार्गेट भी निर्णय का हिस्सा हैं, हालाँकि मुख्य कसौटी इंटरैक्शन व्यवहार ही रहता है। SpriteView, Canvas

टकराव प्रतिक्रिया को सूचनाओं से अलग कॉन्फ़िगर करें

अपने आकारों और सीमा को श्रेणियाँ दें, फिर दोनों इंटरैक्शन मास्क स्पष्ट रूप से कॉन्फ़िगर करें:

  • categoryBitMask उन श्रेणियों की पहचान करता है जिनसे कोई बॉडी संबंधित है।
  • collisionBitMask उन श्रेणियों को चुनता है जो उस बॉडी को भौतिक रूप से प्रभावित कर सकती हैं।
  • contactTestBitMask चुनी हुई श्रेणियों के लिए संपर्क सूचनाएँ माँगता है।

टकराव मास्क हर बॉडी के लिए अलग-अलग जाँचे जाते हैं। दो गतिशील आकारों के बीच सामान्य पारस्परिक प्रतिक्रिया के लिए, दोनों बॉडी को दूसरे की श्रेणी पर प्रतिक्रिया देने के लिए कॉन्फ़िगर करें। संपर्क रिपोर्टिंग का नियम अलग है: किसी मेल खाती श्रेणी और संपर्क-मास्क की तुलना किसी भी दिशा में सूचना पैदा कर सकती है। सिर्फ़ सूचनाएँ चालू करने से भौतिक अवरोध कॉन्फ़िगर नहीं होता। collisionBitMask, contactTestBitMask

यदि बॉडी भौतिक रूप से प्रतिक्रिया देती हैं, लेकिन कोई कॉलबैक नहीं आता, तो संपर्क मास्क और फ़िज़िक्स वर्ल्ड के संपर्क डेलीगेट की जाँच करें। यदि आकार एक-दूसरे से गुज़रते हुए कॉलबैक देते हैं, तो टकराव मास्क और मूवमेंट कंट्रोलर देखें। इन जाँचों से सूचना कॉन्फ़िगरेशन और वास्तविक गति की समस्या अलग-अलग समझ आती है।

उपयोगकर्ता के ड्रैग करने पर स्थिति कौन नियंत्रित करे?

SpriteKit ड्रैग के लिए स्पष्ट कंट्रोलर चाहिए। फ़िज़िक्स इंजन अपने-आप पॉइंटर का अनुसरण करने वाला इंटरैक्शन नहीं बन जाता। पहले तय किए गए व्यवहार के आधार पर सीधे स्थान-निर्धारण या सिमुलेशन-आधारित गति चुनें।

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

सिमुलेशन-आधारित ड्रैग में, पॉइंटर की स्थिति को लक्ष्य के रूप में बनाए रखें और गतिशील बॉडी को उसकी ओर ले जाने के लिए बलों या स्प्रिंग-आधारित कंट्रोलर का उपयोग करें। तब बॉडी को हिलाते समय सिमुलेशन संपर्कों का समाधान कर सकता है। इसका समझौता यह है कि जब कोई दूसरी वस्तु गति रोकती है, तो पॉइंटर से जानबूझकर देरी या दूरी बनी रहती है। SpriteKit बल लगाने का समर्थन करता है, और SKPhysicsJointSpring दो फ़िज़िक्स बॉडी को स्प्रिंग व्यवहार से जोड़ता है। ये आधारभूत सुविधाएँ हैं, जिनके लिए ऐप-विशिष्ट ट्यूनिंग चाहिए। SKPhysicsBody, SKPhysicsJointSpring

जब फ़िज़िक्स से उसी स्थिति को स्वतंत्र रूप से नियंत्रित करने की अपेक्षा हो, तब पॉइंटर की स्थितियाँ लगातार असाइन करने से बचें। SpriteKit का दस्तावेज़ित फ़्रेम क्रम ऐप अपडेट, ऐक्शन, फ़िज़िक्स और बाद के कॉलबैक को अलग-अलग चरणों में चलाता है। स्थिति का नियंत्रण बाँटने का उपयोगी नियम यह है: इनपुट ड्रैग लक्ष्य अपडेट करे, सीन लॉजिक कंट्रोलर लागू करे और फ़िज़िक्स बॉडी की परिणामी स्थिति निकाले। फ़्रेम-चक्र घटनाओं पर प्रतिक्रिया

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

macOS इनपुट को फ़्रेमवर्क सीमाओं के पार कैसे जाना चाहिए?

कार्यक्षेत्र के लिए एक इनपुट नियंत्रक चुनें। Canvas कार्यान्वयन अपने इंटरैक्शन सतह पर SwiftUI DragGesture लगा सकता है। कस्टम AppKit सतह रिस्पॉन्डर इवेंट संभाल सकती है; mouseDragged(with:) बायाँ माउस बटन दबा होने पर गति प्राप्त करता है। ओवरले किया हुआ SwiftUI जेस्चर और AppKit हैंडलर एक ही चयनित आइटम को स्वतंत्र रूप से न चलाएँ। DragGesture, mouseDragged(with:)

AppKit से SpriteKit ब्रिज बनाते समय, हर सीमा पर कॉर्डिनेट बदलें। NSEvent.locationInWindow सामान्यतः संबंधित विंडो के आधार कॉर्डिनेट सिस्टम में व्यक्त होता है। उस बिंदु को होस्टिंग दृश्य के कॉर्डिनेट में बदलें, फिर दृश्य कॉर्डिनेट से सीन कॉर्डिनेट में बदलें। बाद वाले चरण के लिए Apple convertPoint(fromView:) देता है और इसे कॉल करने से पहले सीन प्रस्तुत होना आवश्यक है। नोड की स्थिति उसके पैरेंट के कॉर्डिनेट सिस्टम में व्यक्त होती है, इसलिए नेस्टेड नोड के लिए एक और रूपांतरण ज़रूरी हो सकता है। locationInWindow, convertPoint(fromView:), position

सीधे SwiftUI होस्टिंग के लिए SpriteView इस्तेमाल करें। यदि आपको कस्टम AppKit दृश्य चाहिए, तो NSViewRepresentable निर्माण, अपडेट, समन्वय और सफ़ाई देता है। प्रतिनिधित्व किए गए दृश्य का लेआउट SwiftUI को संभालने दें: Apple स्पष्ट रूप से चेतावनी देता है कि उसका प्रबंधित फ़्रेम या बाउंड्स स्वयं असाइन न करें। NSViewRepresentable

हर बार SwiftUI दृश्य सामग्री की पुनर्गणना पर नया सीन बनाने के बजाय सीन को किसी स्थिर स्वामी के पास रखें। Canvas के लिए आइटम मॉडल को भी इसी तरह बनाए रखें। SwiftUI के मॉडल दस्तावेज़ बताते हैं कि प्रबंधित स्थिति दृश्य के दोबारा बनने पर किसी इंस्टेंस को कैसे बनाए रखती है; इसका Observation तरीका macOS 14 या बाद का संस्करण माँगता है। सीन कमांड और मॉडल स्नैपशॉट को सोच-समझकर स्थानांतरित करें, ताकि दो परिवर्तनशील प्रतियाँ स्थिति तय करने की होड़ न करें। अपने ऐप में मॉडल डेटा प्रबंधित करना

किसी एक तरीके को चुनने से पहले क्या जाँचना चाहिए?

दृश्य सजावट जोड़ने से पहले, कठिन इंटरैक्शन जाँचने के लिए एक छोटा कृत्रिम कार्यक्षेत्र इस्तेमाल करें:

  1. आकार के किनारे के पास पकड़ें और पुष्टि करें कि शुरुआती ऑफ़सेट बना रहता है।
  2. धीरे-धीरे किसी दूसरे आइटम की ओर ड्रैग करें, फिर उसी के आर-पार एक बड़ी पॉइंटर गति के साथ दोहराएँ।
  3. दो पड़ोसी आकारों वाले कोने की ओर ड्रैग करें।
  4. किसी दूसरे आइटम को छूते हुए छोड़ें और देखें कि वह अपेक्षा के अनुसार स्थिर होता है या नहीं।
  5. कार्यक्षेत्र का आकार बदलें और चयन, सीमाएँ तथा कॉर्डिनेट रूपांतरण जाँचें।
  6. आसपास की SwiftUI सामग्री फिर से बनाएँ और पुष्टि करें कि आइटमों की स्थिति बनी रहती है।
  7. ड्रैग बीच में रोकें और पुष्टि करें कि चयन तथा कोई भी अस्थायी फ़िज़िक्स सेटिंग साफ़ हो जाती है।

SpriteKit में बॉडी की ज्यामिति इच्छित टकराव क्षेत्र से मेल खाती है या नहीं, यह जाँचने के लिए SKView.showsPhysics चालू करें। छोटे और तेज़ी से चलने वाले बॉडी के लिए usesPreciseCollisionDetection का मूल्यांकन करें; Apple इसके अधिक कंप्यूटेशनल खर्च और सामान्य फ़्रेम-आधारित जाँच से छूट सकने वाले टकरावों का पता लगाने में इसकी भूमिका का दस्तावेज़ देता है। इसे सुसंगत ड्रैग कंट्रोलर की जगह इस्तेमाल नहीं करना चाहिए। SKView, usesPreciseCollisionDetection

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

स्रोत