Utworzono SKSpriteNode
o nazwie powiedzmy Mapa, która ma zdefiniowaną ścieżkę krawędzi (prosty kształt wielokąta).SpriteKit SKPhysicsBody z wewnętrznymi krawędziami
Co Próbuję dowiedzieć się, jak dodać kilka inne ścieżki brzegowych, które działają jako wewnętrznych krawędziach mapą. Tak jakby "mapa" jako całość miała w rzeczywistości otwory. Jakiś wewnętrznych kształtach brzegowych, które mogą działać mapą jako całości jednej ścieżki krawędzi (jak pokazano poniżej)
I rozumie, że istnieje metoda, która pozwala na utworzenie SKPhysicsBody
z ciał (niektóre NSArray), takich jak taki
Czy ta metoda faktycznie generuje to, co pokazałem na obrazie? Zakładając, że bodiesArray
zawiera 3 SKSpriteNode
jest każdy z określonej drogi z użyciem takiego sposobu:
+ (SKPhysicsBody *)bodyWithEdgeChainFromPath:(CGPathRef)path
, z utworzeniem ścieżki podobne takie
SKSpriteNode *innerNode1 = [SKSpriteNode spriteNodeWithImageNamed:@"map"];
CGMutablePathRef innerNode1Path = CGPathCreateMutable();
CGPathMoveToPoint(mapPath, NULL, 1110, 1110);
CGPathAddLineToPoint(mapPath, NULL, <some x1>, <some y1>);
CGPathAddLineToPoint(mapPath, NULL, <some x2>, <some y2>);
CGPathAddLineToPoint(mapPath, NULL, <some x3>, <some y3>);
.
.
.
CGPathCloseSubpath(mapPath);
innerNode1.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:innerNode1Path];
[bodiesArray addObject:innerNode1];
// Repeat for other 2 nodes
I zrozumieć, że alternatywą byłoby utworzyć 3 oddzielne węzły z lokalizacją i kształtem zamierzonych "dziur", ale łączę się, aby uniknąć tworzenia większej liczby węzłów niż potrzebuję. Jeśli ktokolwiek może potwierdzić, co próbuję zrobić, jest poprawny, lub może zaproponować alternatywę, której nie jestem świadomy.
UWAGA: czy to, co robię jest poprawne, ale brakuje mi czegoś, byłbym wdzięczny, jeśli ktoś może mi pokazać właściwą drogę do tego, co próbuję zrobić (nawet prosty przykład kwadratu o wewnętrzny mniejszy kwadrat byłby świetny). Dzięki!
EDYCJA 1: Poniżej znajduje się fragment kodu, którego używam jako próbę utworzenia "wewnętrznych granic". W tym przypadku problem polega na tym, że podczas rysowania zarówno zewnętrznego, jak i wewnętrznego prostokąta, gdy dodaję wewnętrzny rect do mapy bodyWithBodies
, uzyskuje on pełną kontrolę nad wykrywaniem kolizji, usuwając wszystkie kontrole kontaktowe z zewnętrznej prostokątnej powłoki. Kiedy usunąć bodyWithBodies
wraca do normy z pokazując oba prostokąty, zewnętrzna posiada detekcję kolizji (nie pozwala mi przejść), podczas gdy wewnętrzna jeden ma nic ... tak blisko
// 1 Create large outer shell Map
CGRect mapWithRect = CGRectMake(map.frame.origin.x + offsetX, map.frame.origin.y + offsetY, map.frame.size.width * shrinkage, map.frame.size.height * shrinkage);
self.physicsWorld.gravity = CGVectorMake(0.0, 0.0);
self.physicsWorld.contactDelegate = self;
// 2 Create smaller inner boundary
CGRect innerRect = CGRectMake(100, 100, 300, 300);
SKPhysicsBody *body = [SKPhysicsBody bodyWithEdgeLoopFromRect:innerRect];
body.categoryBitMask = wallCategory;
NSArray *bodyArray = [NSArray arrayWithObject:body];
// 3 Add bodies to main Map body
myWorld.physicsBody = [SKPhysicsBody bodyWithBodies:bodyArray];
myWorld.physicsBody.categoryBitMask = wallCategory;
if ([[levelDict objectForKey:@"DebugBorder"] boolValue] == YES) {
// This will draw the boundaries for visual reference during testing
[self debugPath:mapWithRect];
[self debugPath:innerRect];
}
EDIT 2 podejście works..by tylko dodanie nowego węzła z takich samych właściwościach jak zewnętrzna rect:
SKPhysicsBody *innerRectBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:innerRect];
innerRectBody.collisionBitMask = playerCategory;
innerRectBody.categoryBitMask = wallCategory;
SKNode *innerBoundary = [SKNode node];
innerBoundary.physicsBody = innerRectBody;
[myWorld addChild: innerBoundary];
... ale bardzo chciałbym czystsze rozwiązanie, które nie wymaga dodatkowych węzłów I .. myśli?
To może być to, czego szukasz https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKPhysicsBody_Ref/#//apple_ref/occ/clm/SKPhysicsBody/bodyWithTexture: alphaThreshold: size: – 0x141E
W mojej edycji pokazałem, co zrobiłem, ale (jak wyjaśniono) nie całkiem. Wiem, że mogę utworzyć oddzielny "węzeł", który może naśladować wydajność większej zewnętrznej powłoki, ale znowu, staram się tylko uniknąć większego obciążenia procesora. Pomyślałem, że coś takiego powinno być możliwe, biorąc pod uwagę zakres użyteczności Apples z SpriteKit .. :( –
ponownie sprawdź swoje maski kolizyjne i kontaktowe – dragoneye