2015-01-07 9 views
5

Also für die App, an der ich arbeite, habe ich zwei Würfel kollidieren. Ich überprüfe das auf die übliche Weise. Die App sagt mir, wenn sie in meiner "didBeginContact" -Methode kollidieren.SpriteKit - Bestimme Seite A Quadrat Zusammengefasst mit

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

So weiß ich, wo die Kollision stattfindet, sondern weil es zwei Quadrate ist, kann es an der Seite, einschließlich der Ecken an jedem Punkt sein. Also wie würde ich prüfen, ob die Kollision ausschließlich links/rechts/oben/unten stattfindet?

Bearbeiten: Richtige Antwort: Vielleicht nicht der sauberste Weg, es zu tun, aber es funktioniert. Hoffentlich hilft es jemandem in der Zukunft.

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; 
     } 
    } 
} 

Zusätzlichen relevanten Code hinzugefügt. Es ist mein Code, also gibt es Variablen unter anderem, aber Sie sollten in der Lage sein, es herauszufinden.

Antwort

3

Der einfachste Weg ist, Kind Sprites die oberen, linken, rechten, unteren Quadrate hinzuzufügen. Fügen Sie Physikkörper diesen hinzu, und dann können Sie sagen, wo die Dinge kollidieren. Ich würde empfehlen, diese Methode zuerst zu probieren, es sei denn, Sie haben viele Quadrate auf dem Bildschirm.

Wenn Sie eine Menge Quadrate auf dem Bildschirm haben und Ihre Leistung besorgt sind. Dann benutze vielleicht contact.contactPoint und konvertiere diesen Punkt in quadratische Koordinaten. Wenn man den Mittelpunkt des Quadrats, den Winkel der Drehung der Quadrate und diesen Punkt betrachtet, sollte man erkennen können, wo das Quadrat kollidiert ist. Das würde etwas Mathe erfordern .. und ich hatte Angst, diese Art von Lösung zu schreiben, wenn die erste alles sein könnte, was Sie wirklich brauchen.

+0

Ihre erste Methode funktioniert wirklich gut, ich weiß nicht, warum ich nicht daran gedacht habe. Vielen Dank! – CMilby

+1

stört es Sie als die richtige Antwort zu markieren, wenn es Ihnen geholfen hat? – hamobi

4

Ich denke, den besten Weg, um festzustellen, welche Seite in Ihrem Kontakt beteiligt ist (oben, links, unten, rechts) ist:

  • die Punkte durch einen Zentrierkreuz für bis Endivie berechnen , unten, links und rechts Seiten (zum Beispiel, wenn Sie ein Quadrat Sprit haben ..)

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) 
  • Berechne den Abstand zwischen der Contact und jedem Punkt Seiten (oben, links, rechts und unten)

Dieser Schritt mit dieser kleinen Funktion möglich sein kann:

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))) 
} 

Danach ist der Punkt, der mit der niedrigsten berechneten Entfernung verbunden ist, der dem Kontaktpunkt nächstgelegene Punkt.

Was sind die Vorteile dieser Methode:

  1. Sie malen nicht Zombies oder Geister Knoten und relative Physic Körper
  2. Diese Methode funktioniert auch in einem dynamischen wandelbar CGPath, nicht nur mit einem bekannten rechteckigen Grenzen
  3. Ist schnell, ein paar Zeilen Code und wenn Sie andere Zeilen hinzufügen können Sie in der Lage, auch Diagonalen zu bestimmen und präzisieren Sie Ihre Algorithmus.