2016-08-23 14 views
5

Mam 2 SKSpriteNode:Problemy do wykrywania, czy CGPoint jest wewnątrz kwadratowy (kształt rombu)

  • prosty kwadratowy (A)
  • tym samym placu z obrotu (-45 °) (B)

Muszę sprawdzić, w dowolnym momencie, czy środek innego SKSpriteNode (kulka) znajduje się wewnątrz jednego z tych kwadratów. Kula i kwadraty mają tego samego rodzica (główna scena).

override func update(_ currentTime: TimeInterval) { 

    let spriteArray = self.nodes(at: ball.position) 

    let arr = spriteArray.filter {$0.name == "square"} 

    for square in arr { 
     print(square.letter) 

     if(square.contains(self.puck.position)) { 
      print("INSIDE") 
     } 

    } 
} 

Za pomocą prostego kwadratu (A) mój kod działa poprawnie. Dane są prawidłowe. Wiem, o każdej porze, czy centrum CGPoint znajduje się wewnątrz czy na zewnątrz kwadratu.

Ale z kwadratem z obrotem (B) dane nie są zgodne z oczekiwaniami. Punkt CGPoint jest wykryty wewnątrz, gdy tylko znajdzie się na polu, w którym znajduje się kształt rombu.

demo

Kwadraty SKSpriteNode są tworzone przez edytor poziomów.

Jak mogę zrobić, aby uzyskać prawidłowy wynik dla kształtu diamentu?

EDIT 1

Korzystanie

view.showsPhysics = true 

widzę granice wszystkich SKSpriteNode z physicsBody. Granica mojego diamentowego kwadratu to kwadrat diamentowy, a nie szary kwadrat.

square.frame.size -> return the grey area 
square.size -> return the diamond-square 

W dokumentacji Apple, func nodes(at p: CGPoint) -> [SKNode], metoda jest o węźle, a nie ramy, więc dlaczego to nie działa?

+0

Ewentualnie, ramka nie korzysta alfa maskę? Możesz użyć '.physicsBody' i kolizji, aby uzyskać największą dokładność tego. Nie mam żadnego kodu pod ręką, ale możesz to zrobić na pewno za pomocą 'SKPhysicsContactDelegate. http://stackoverflow.com/questions/27576149/detect-collision-between-two-objects-in- swift – Fluidity

+0

Próbowałem użyć .physicsBody i kolizji, ale dzięki tej metodzie wiem, kiedy piłka ma kontakt z kwadratem. To nie jest to, czego potrzebuję. Interesuje mnie kontakt ze środkiem piłki (CGPoint) i kwadratem. Nie jest to dokładnie to samo. – cmii

+0

cóż, @ cmi, myślę, że nadal możesz używać co najmniej '.frame.intersects', ale musisz ustawić ramkę jako maskę alfa. W tej chwili widzimy cały kwadrat (szary obszar) jako obszar kontaktu, podczas gdy maska ​​alfa pokazuje tylko obszar niebieskiego diamentu. Jeśli się mylę, to jedyny inny sposób, w jaki mogę myśleć to po prostu zrobić matematykę i odjąć 4 trójkąty (szare obszary) otaczające niebieski diament. – Fluidity

Odpowiedz

2

Jest wiele sposobów na zrobienie tego, zazwyczaj lubię pracować ze ścieżkami, więc jeśli masz doskonały diament, jak opisujesz chciałbym zaoferować inną drogę niż komentarze, możesz stworzyć ścieżkę idealnie dopasowaną do diamentu z UIBezierPath ponieważ mają metodę containsPoint:

let f = square.frame 
var diamondPath = UIBezierPath.init() 
diamondPath.moveToPoint(CGPointMake(f.size.width-f.origin.x,f.origin.y)) 
diamondPath.addLineToPoint(CGPointMake(f.origin.x,f.size.height-f.origin.y)) 
diamondPath.addLineToPoint(CGPointMake(f.size.width-f.origin.x,f.size.height)) 
diamondPath.addLineToPoint(CGPointMake(f.size.width,f.size.height-f.origin.y)) 
diamondPath.closePath() 
if diamondPath.containsPoint(<#T##point: CGPoint##CGPoint#>) { 
    // point is inside diamond 
} 
+1

Ormano, to dokładnie to, czego szukałem (jeśli robi to, o czym myślę, że to robi) ... bardzo eleganckie rozwiązanie, bez konieczności "oszukiwania" go lub wymyślania formuły. Zamierzam to snipperować również dla siebie :) – Fluidity

+0

Używanie SKShapeNode wydaje się najlepszym rozwiązaniem dla mnie i procesora. – cmii

Powiązane problemy