2016-10-30 24 views
10

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

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

मैं एक दूसरे से अलग टक्कर bitmasks बताए द्वारा कि इस मुद्दे को हल करने की कोशिश की:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let texture = SKTexture(imageNamed: "pokeball") 
    let object = SKSpriteNode(texture: texture) 

    object.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: object.size.width,height: object.size.height)) 
    object.physicsBody?.affectedByGravity = false 
    object.yScale = 0.5 
    object.xScale = 0.5 

    for t in touches { 
     object.position = t.location(in: self) 
    } 
    self.addChild(object) 
    object.physicsBody?.collisionBitMask = UInt32(4) 
    object.physicsBody?.applyForce(CGVector(dx: 0, dy: 10)) 

} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let texture = SKTexture(imageNamed: "purple") 
    let second = SKSpriteNode(texture: texture) 
    let impulse : Double = 20 
    let x = (impulse * Double(cosf(45))) 
    let y = Double(impulse * Double(sinf(45))) 
    let vector = CGVector(dx: x, dy: y) 
    second.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: second.size.width,height: second.size.height)) 

    second.yScale = 1.5 
    second.xScale = 1.5 
    second.physicsBody?.isDynamic = true 

    for t in touches { 
     second.position = t.location(in: self) 
    } 
    self.addChild(second) 
    second.physicsBody?.collisionBitMask = UInt32(1) 
    second.physicsBody?.applyImpulse(vector) 
} 

तो वस्तु 4 का बिटमास्क है:

object.physicsBody?.collisionBitMask = UInt32(4) 

और दूसरा 1 का बिटमास्क है:

second.physicsBody?.collisionBitMask = UInt32(1) 

मैंने सिम्युलेटर चलाया और वे अभी भी एक-दूसरे के साथ टकराने लगे हैं, इसलिए मैं ऑनलाइन गया और लू कुछ उत्तरों के लिए: मुझे एक ऐसा लगता है जो मुझे लगता है कि मुझे संख्याओं का उपयोग करना चाहिए:

ये बिटमास्क हैं, आप मनमानी संख्याओं का उपयोग नहीं कर सकते हैं 1,2,3,4,5 - आपको 1,2 का उपयोग करना होगा, 4,8,16 और इसी तरह -

क्या कोई समझा सकता है क्यों? अभी भी टकराने: हालांकि, कि इस मुद्दे क्योंकि मैं 1 और 4 उपयोग कर रहा था

अगला सवाल मैं में भाग कहा कि मैं द्विआधारी संख्या (0100) और (0010) का इस्तेमाल किया था, मैं उन्हें करने की कोशिश की, एक ही मुद्दा नहीं था। Collisions

क्या किसी को पता है कि क्यों यह हो रहा है:

मैं टकराव की एक तस्वीर छोड़ देंगे? अग्रिम में मेरी माफी माँगती है अगर यह वास्तव में गूंगा गलती है या कुछ जो पहले से ही पूछा जा चुका है, तो मुझे बस यह नहीं मिला।

+0

इस पर एक नज़र डालें: http://stackoverflow.com/a/39064710/3402095 श्रेणी बिट मास्क का डिफ़ॉल्ट मान देखें। यह सब वहाँ समझाया गया है। – Whirlwind

+0

निर्दिष्ट करना कि एक भौतिकी निकाय का टकराव है 4 का बिटमैस्क का मतलब है कि यह भौतिकी के साथ टकराता है, जिनकी श्रेणी 4 बिटबैस्क है (वास्तव में उस पर '4' बिट सेट है, लेकिन चलिए सबसे सरल उदाहरण से शुरू करते हैं)। यदि आपने किसी भी श्रेणी बिटमैस्क को देखकर परेशान नहीं किया है, तो चीजें काम नहीं करने जा रही हैं। –

उत्तर

7

इन विषयों पर बहुत सारे दस्तावेज हैं, लेकिन यहां एक व्यावहारिक उदाहरण है।

categoryBitMasks

की शक्ति मान लें कि आपने तीन नोड्स pool, basketball और bowlingball का एक संग्रह है। अब, जाहिर है, हम एक दूसरे के साथ टकराने के लिए basketball और bowlingball चाहते हैं।

basketball.physicsBody?.collisionBitMask = UInt32(2) 
bowlingball.physicsBody?.collisionBitMask = UInt32(2) 

महान: तो तुम इतनी तरह collisionBitMasks निर्धारित किया है। अब, हम pool के नीचे डूबने के लिए pool (एक स्पलैश के अधिक हो सकते हैं, लेकिन मेरे साथ भालू) के लिए bowlingball को नीचे डुबोने के लिए चाहते हैं। हम यह कैसे करेंगे?हम कोशिश कर सकते:

pool.physicsBody?.collisionBitMask = UInt32(2) // ? 

लेकिन रुकिए, कि basketball बनाना होगा और bowlingballpool से टकराते। पूल के साथ टकराने के लिए हम केवल basketball चाहते हैं, जबकि हम bowlingballpool को अनदेखा करने के लिए चाहते हैं और सीधे टकराव के बिना नीचे सिंक करना चाहते हैं। जहां categoryBitMask रों उपयोगी हो यह वह जगह है:

let basketballBitMask  = UInt32(1) 
let bowlingballBitMask = UInt32(2) 
let poolBitMask   = UInt32(4) // Why 4? See next section 

basketball.physicsBody?.categoryBitMask = basketballBitMask 
bowlingball.physicsBody?.categoryBitMask = bowlingballBitMask 
pool.physicsBody?.categoryBitMask   = poolBitMask 

क्योंकि प्रत्येक वस्तु में डाला गया एक अद्वितीय संख्या है, अब आप ले सकते हैं और जो वस्तुओं आप किसी अन्य वस्तु चाहते हैं, उससे टकराने के लिए चुन सकते हैं:

// basketball physics body collides with bowlingball(2) OR pool(4) 
basketball.physicsBody?.collisionBitMask = bowlingballBitMask | poolBitMask 
// ('|' = logical OR operator) 

// bowlingball physics body only collides with basketball(1) 
bowlingball.physicsBody?.collisionBitMask = basketballBitMask 

// pool physics body only collides with basketball(1) 
pool.physicsBody?.collisionBitMask   = basketballBitmask 

यदि आप सुनिश्चित नहीं हैं कि अजीब '|' प्रतीक कर रहा है, मैं उन्नत ऑपरेटरों पर swift documentation की अत्यधिक अनुशंसा करता हूं ताकि आप यह समझ सकें कि यहां क्या हो रहा है।

क्यों टक्कर बिटमैस्क का उपयोग न करें?

ठीक है इसलिए हमने कुछ बिट मास्क सेट किए हैं। लेकिन वे कैसे उपयोग किए जाते हैं? अगर हमारे पास केवल दो वस्तुएं हैं तो हम टक्कर की तुलना नहीं कर सकते हैं बिटमैस्क?

बस शब्दों में कहें, यह सिर्फ यह नहीं है कि यह कैसे काम करता है।

: (परिणाम एक ही है या इसके विपरीत) एक bowlingball pool, SpriteKit भौतिकी इंजन होगा और ('&') एक साथ bowlingball के pool साथ categoryBitMask के collisionBitMask साथ संपर्क में आता है
objectsShouldCollide = (bowlingball.physicsBody?.categoryBitMask & 
         pool.physicsBody?.collisionBitMask) 
// objectsShouldCollide = (ob010 & 0b100) = 0b000 

क्योंकि bowlingball के categoryBitMask और pool के collisionBitMask आम में शून्य बिट्स है, objectsShouldCollide शून्य के बराबर है, और SpriteKit टकराने से वस्तुओं बंद हो जाएगा।

लेकिन, आपके मामले में, आप अपनी ऑब्जेक्ट्स categoryBitMask एस सेट नहीं कर रहे हैं। इसलिए उनके पास 2^32, या 0xFFFFFFFF (hexadecimal representation) या बाइनरी, 0b11111111111111111111111111111111 का डिफ़ॉल्ट मान है। इसलिए जब एक "वस्तु" एक "द्वितीय" वस्तु हिट, SpriteKit करता है:

objectsShouldCollide = (0b11111111111111111111111111111111 & // Default categoryBitMask for "object" 
         0b00000000000000000000000000000001) // collisionBitMask for "second" object 
//     = 0b00000000000000000000000000000001 

तो जब आप निर्धारित नहीं किया है object के categoryBitMask, कोई बात नहीं क्या आप second वस्तु की collisionBitMask के रूप में सेट, objectsShouldCollide होगा शून्य कभी नहीं, और वे हमेशा टकराएंगे।

नोट: आप ऑब्जेक्ट का collisionBitMask 0 पर सेट कर सकते हैं; लेकिन फिर वह वस्तु कभी भी किसी भी चीज़ से टकराने में सक्षम नहीं होगी। categoryBitMasks

के लिए 2 (0,1,2,4,8, आदि) के

का उपयोग शक्तियां अब मान लीजिए कि हम कई bowlingball रों कि एक दूसरे से टकरा शामिल करना चाहता हैं। आसान:

bowlingball.physicsBody?.collisionBitMask = basketballBitMask | bowlingballBitMask 
// bowlingball collision bit mask (in binary) = 0b10 | 0b01 = 0b11 
// bowlingball collision bit mask (in decimal) = 2 | 1 = 3 

यहां आप देख सकते हैं कि अगर हम pool रों UInt32 को physicsCategory स्थापित किया था (3), यह अब एक bowlingball या basketball से अलग पहचाना होगा।

आगे सुझाव

उद्देश्य के साथ name चर करना सीखें, भले ही आप अभी परीक्षण के लिए उन्हें का उपयोग कर रहे हैं (हालांकि, संयोग से, "object और second वस्तु" बहुत अच्छी तरह से काम किया)।

bitmasks अपने कोड को सरल बनाने और पठनीयता में सुधार के लिए एक struct का उपयोग करें:

struct PhysicsCategory { 
    static let Obj1   : UInt32 = 0b1 << 0 
    static let Obj2   : UInt32 = 0b1 << 1 
    static let Obj3   : UInt32 = 0b1 << 2 
    static let Obj4   : UInt32 = 0b1 << 3 
} 

obj1.physicsBody?.categoryBitmask = PhysicsCategory.Obj1 // etc 
+0

मुझे नहीं लगता कि आपको सीधे श्रेणी बिट मास्क की आवश्यकता क्यों है जब मैं सीधे टक्कर बिट मास्क में जा सकता हूं? क्या आप कृपया समझा सकते हैं? जब मैं टकराव बिट मास्क संशोधित करता हूं तो डिफ़ॉल्ट मान ओवर्रिडन नहीं है? – Pablo

+0

नहीं। एक श्रेणी बिट मास्क टक्कर बिट मास्क के समान नहीं है। मेरे अद्यतन उत्तर के माध्यम से पढ़ें। – Ralph

2

तुम क्यों डाउनलोड करने और नहीं खेलते हैं इस सरल स्प्राइट-किट परियोजना के साथ? यह विभिन्न ज्यामितीय आकार बनाता है, उनमें से कुछ को टक्कर मारने के लिए सेट करता है, कुछ संपर्क करने के लिए, checkPhysics() फ़ंक्शन का उपयोग यह दिखाने के लिए करता है कि क्या होने जा रहा है और फिर आप आकार को झटका देते हैं।

Attack button in SpriteKit

इसे करने के लिए के रूप में कोई प्रश्न कामकाज है और मैं कोशिश करते हैं और समझाने के लिए बहुत खुशी हो जाएगा।

+1

दस्तावेजों में लिंक्ड प्रोजेक्ट के लिए आपको एक ओवरवोट से अधिक पुरस्कृत करने का एक तरीका होना चाहिए। बहुत अच्छा! – Confused

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