2015-01-07 14 views
5

के साथ साइड ए स्क्वायर को निर्धारित करें, इसलिए ऐप के लिए मैं काम कर रहा हूं, मेरे पास दो क्यूब टकराव हैं। मैं इसे मानक तरीके से जांचता हूं। ऐप मुझे बताता है कि जब वे मेरी "didBeginContact" विधि में टकराते हैं।स्प्राइटकिट -

-(void)didBeginContact:(SKPhysicsContact *)contact { 
    if (contact.bodyA.categoryBitMask == WALL_CATEGORY && contact.bodyB.categoryBitMask == CHARACTER_CATEGORY) { 
     CGPoint point = contact.contactPoint; 
    } 
} 

तो मुझे पता है जहां टकराव होता है, लेकिन क्योंकि यह दो वर्गों है यह कोनों सहित ओर के साथ किसी भी बिंदु पर हो सकता है। तो मैं कैसे जांच करूंगा कि बाएं/दाएं/ऊपर/नीचे टकराव विशेष रूप से है?

संपादित करें: सही उत्तर: ऐसा करने का सबसे साफ तरीका नहीं हो सकता है लेकिन यह काम करता है। उम्मीद है कि यह भविष्य में किसी की मदद करेगा।

m_lNode = [SKNode node]; 
m_lNode.position = CGPointMake(-(CHARACTER_SIZE/2), 0); 
m_lNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)]; 
m_lNode.physicsBody.allowsRotation = NO; 
m_lNode.physicsBody.usesPreciseCollisionDetection = YES; 
m_lNode.physicsBody.categoryBitMask = CHARACTER_L_CATEGORY; 

m_rNode = [SKNode node]; 
m_rNode.position = CGPointMake((CHARACTER_SIZE/2), 0); 
m_rNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)]; 
m_rNode.physicsBody.allowsRotation = NO; 
m_rNode.physicsBody.usesPreciseCollisionDetection = YES; 
m_rNode.physicsBody.categoryBitMask = CHARACTER_R_CATEGORY; 

m_tNode = [SKNode node]; 
m_tNode.position = CGPointMake(0, (CHARACTER_SIZE/2)); 
m_tNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width , 1)]; 
m_tNode.physicsBody.allowsRotation = NO; 
m_tNode.physicsBody.usesPreciseCollisionDetection = YES; 
m_tNode.physicsBody.categoryBitMask = CHARACTER_T_CATEGORY; 

m_bNode = [SKNode node]; 
m_bNode.position = CGPointMake(0, -(CHARACTER_SIZE/2)); 
m_bNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width, 1)]; 
m_bNode.physicsBody.allowsRotation = NO; 
m_bNode.physicsBody.usesPreciseCollisionDetection = YES; 
m_bNode.physicsBody.categoryBitMask = CHARACTER_B_CATEGORY; 

[m_character addChild:m_tNode]; 
[m_character addChild:m_bNode]; 
[m_character addChild:m_lNode]; 
[m_character addChild:m_rNode]; 

-(void)didBeginContact:(SKPhysicsContact *)contact { 
    if (contact.bodyA.categoryBitMask == WALL_CATEGORY) { 
     switch (contact.bodyB.categoryBitMask) { 
      case CHARACTER_T_CATEGORY: 
       NSLog(@"Top"); 
       m_isHitTop = true; 
       break; 
      case CHARACTER_B_CATEGORY: 
       NSLog(@"Bottom"); 
       m_isHitBottom = true; 
       break; 
      case CHARACTER_L_CATEGORY: 
       NSLog(@"Left"); 
       m_isHitLeft = true; 
       break; 
      case CHARACTER_R_CATEGORY: 
       NSLog(@"Right"); 
       m_isHitRight = true; 
       break; 
     } 
    } 
} 

कुछ प्रासंगिक कोड जोड़ा गया। यह मेरा कोड है इसलिए अन्य चीजों के साथ चर है लेकिन आपको इसे समझने में सक्षम होना चाहिए।

उत्तर

3

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

यदि आपके पास स्क्रीन पर चौकों का एक टन है और आप प्रदर्शन के बारे में चिंतित हैं। तो शायद contact.contactPoint का उपयोग करें और उस बिंदु को वर्ग निर्देशांक में कनवर्ट करें। वर्ग के केंद्र बिंदु, वर्ग रोटेशन के कोण और उस बिंदु को देखते हुए, आपको यह बताने में सक्षम होना चाहिए कि वर्ग कहाँ से टक्कर लगी है। इसके लिए कुछ गणित की आवश्यकता होगी .. और मुझे उस तरह के समाधान को लिखने से डर था जब पहली बार आपको वास्तव में आवश्यकता हो सकती है।

+0

आपकी पहली विधि वास्तव में अच्छी तरह से काम करती है, मुझे नहीं पता कि मैंने इसके बारे में क्यों नहीं सोचा। धन्यवाद! – CMilby

+1

क्या आपको यह सही जवाब के रूप में चिह्नित करने पर ध्यान देता है अगर इससे आपकी मदद मिली? – hamobi

4

मैं निर्धारित करने के लिए क्या पक्ष अपने संपर्क में शामिल है (ऊपर, बाएँ, नीचे, दाएं ओर) का सबसे अच्छा तरीका सोचना है:

  • अंकअप के लिए एक केंद्रित पार से त्यागा गणना , नीचे, (उदाहरण के लिए यदि आप एक वर्ग स्प्राइट है ..) छोड़ दिया और सही पक्षों

enter image description here

let halfWidth = self.frame.width/2 
let halfHeight = self.frame.height/2 
let down = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y) 
let up = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y+self.frame.size.height) 
let left = CGPointMake(self.frame.origin.x,self.frame.origin.y+halfHeight) 
let right = CGPointMake(self.frame.origin.x+self.frame.size.width,self.frame.origin.y+halfHeight) 
  • ContactPoint और प्रत्येक बिंदु पक्षों के बीच दूरी की गणना (ऊपर, बाएँ, सही और नीचे)

यह कदम इस छोटे से समारोह के साथ संभव हो सकता है:

func getDistance(p1:CGPoint,p2:CGPoint)->CGFloat { 
    let xDist = (p2.x - p1.x) 
    let yDist = (p2.y - p1.y) 
    return CGFloat(sqrt((xDist * xDist) + (yDist * yDist))) 
} 

बाद में, सबसे कम दूरी के साथ शामिल बिंदु संपर्कपॉइंट के नजदीक साइड पॉइंट है।

इस विधि के क्या लाभ हैं:

  1. आप लाश या भूत नोड्स और रिश्तेदार जिस्मानी शरीर को पेंट नहीं है
  2. यह विधि एक गतिशील परिवर्तनशील CGPath, न केवल अंदर भी काम के साथ आयताकार सीमाएं
  3. तेज है, कोड की कुछ पंक्तियां और यदि आप अन्य कुछ पंक्तियां जोड़ते हैं तो आप भी विकर्ण निर्धारित करने में सक्षम हो सकते हैं औरको और सटीक बना सकते हैंएल्गोरिदम।
संबंधित मुद्दे