2016-02-04 6 views
5

Я создал SKSpriteNode, позвони, скажем Карта, у которой есть путь кромки, который я определил (некоторая простая форма многоугольника).SpriteKit SKPhysicsBody с внутренними краями

То, что я пытаюсь выяснить, как добавить несколько других краев дорожки, которые будут действовать в качестве внутренних краев Карты. Как будто «карта» в целом действительно имела отверстия. Своего рода внутренних граничных форм, которые могли бы действовать с Карта в целом: один реберный путь (как показано ниже)

enter image description here ©

Я понимаю, что есть метод, который позволяет для создания SKPhysicsBody с (некоторые NSArray), такие как

Map.physicsBody = [SKPhysicsBody bodyWithBodies:bodiesArray]; 

Этот метод фактически генерирует то, что я показал на изображении? Предполагая, что bodiesArray содержит каждый 3 SKSpriteNode «s с определенной траекторией с использования такого метода:

+ (SKPhysicsBody *)bodyWithEdgeChainFromPath:(CGPathRef)path 

, с созданием пути такого

 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 

Я понимаю, что альтернатива была бы создать- отдельные узлы с расположением и формой предполагаемых «дыр», но я привязываюсь, чтобы не создавать больше узлов, чем мне нужно. Если кто-то может подтвердить, что я пытаюсь сделать, это правильно или, возможно, предложите альтернативу, о которой я не знаю.

ПРИМЕЧАНИЕ: ЕСЛИ то, что я делаю, правильно, но я что-то упускаю, я был бы признателен, внутренний квадрат меньшего размера был бы большим). Благодаря!

EDIT 1: Ниже приведен фрагмент кода, который я использую как попытку создания «внутренних границ». Эта проблема здесь заключается в том, что, хотя внешние и внутренние прямоугольники вырисовываются и отображаются, когда я добавляю внутренний прямоугольник к карте bodyWithBodies, он полностью контролирует обнаружение столкновения, удаляя все управление контактами из внешней прямоугольной оболочки. Когда я удалить bodyWithBodies он возвращается в нормальное русло с показом как прямоугольники, наружный имеет обнаружение столкновений (не позволяет мне пройти), в то время как внутренние один не имеет ничего ... так близко

// 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 Этот подход works..by просто добавить новый узел с теми же свойствами, что и внешнего прямоугольника:

SKPhysicsBody *innerRectBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:innerRect]; 
innerRectBody.collisionBitMask = playerCategory; 
innerRectBody.categoryBitMask = wallCategory; 
SKNode *innerBoundary = [SKNode node]; 
innerBoundary.physicsBody = innerRectBody; 
[myWorld addChild: innerBoundary]; 

... но я очень хотел бы более чистое решение, которое не требует дополнительных узлов .. мысли?

+0

Это может быть то, что вы ищете https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKPhysicsBody_Ref/#//apple_ref/occ/clm/SKPhysicsBody/bodyWithTexture: alphaThreshold: size: – 0x141E

+0

В моем редактировании я показал, что сделал, но (как объяснено) просто не совсем. Я знаю, что могу создать отдельный «узел», который может имитировать производительность большей внешней оболочки, но опять же, я просто стараюсь избегать большего напряжения процессора. Я понял, что что-то вроде этого должно быть возможно, учитывая диапазон удобства использования Яблока с помощью SpriteKit .. :( –

+0

перепроверьте ваши столкновения и маски для контактов – dragoneye

ответ

1

вы не делаете ничего плохого здесь я пришел с примером, в котором я создал два края Rect тела с двумя физическими телами

// добавление тела после некоторого времени использования НОДА

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self addBodyA]; 
    }); 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self addBodyB]; 
    }); 
-(void)addBodyB 
{ 
    SKSpriteNode *node=[SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(20, 20)]; 
    node.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:node.frame.size]; 
    node.position=CGPointMake(550, 420); 
    node.physicsBody.restitution=1; 
    [self addChild:node]; 

} 
-(void)addBodyA 
{ 
    SKSpriteNode *node=[SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(20, 20)]; 
    node.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:node.frame.size]; 
    node.position=CGPointMake(400, 420); 
    node.physicsBody.restitution=1; 
    [self addChild:node]; 

} 
-(void)addEdgesBodies 
{ 
    SKAction *r=[SKAction rotateByAngle:1.0/60 duration:1.0/60]; 

    SKSpriteNode *rect=[SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(300,300)]; 
    rect.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromRect:rect.frame]; 
    rect.position=CGPointMake(500, 400); 
    [self addChild:rect]; 


    // 
    SKSpriteNode *rect1=[SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(100,100)]; 
    rect1.physicsBody=[SKPhysicsBody bodyWithEdgeLoopFromRect:rect1.frame]; 
    rect1.position=CGPointMake(550, 450); 
    [self addChild:rect1]; 


    [rect1 runAction:[SKAction repeatActionForever:r]]; 

} 
[self addEdgesBodies]; 

запомнить края тела приходит с низкими накладными расходами процессора, поэтому не беспокойтесь о производительности, пока ваш многоугольник не будет иметь так много краев.

+0

спасибо за помощь - я ценю это, поэтому этот подход фактически достигнет внутренних интерактивных * граничных условий (как показано на картинке, которую я показал)? это просто создает это обстоятельство визуально –

+0

Я создал большой прямоугольник с меньшим внутренним прямоугольником, но теперь кажется, что внутренний прямоугольник является единственной областью, которая принимает граничные условия, а теперь я могу пройти через внешний прямоугольник. Это было сделано с использованием bodyWithBodies (мой код выше в редактировании моего ответа) –

0

Ваш код для создания пути, а затем его использования в физическом теле выглядит так, как будто это сработает. Как и ваше физическое тело из тел. К сожалению, я не знаю, что SKPhysicsBody может действительно поддерживать дыры, потому что вы не можете переворачивать нормали тела. То, как я читаю документацию по яблокам, состоит в том, что он предназначен для того, чтобы делать такие вещи, как принимать две формы круга и превращать их в одно тело, а не создавать сложную форму. Проблема в том, что наличие отверстия внутри вашей более крупной формы означало бы игнорирование столкновения в этой области.

Вот некоторые альтернативные варианты

Один из вариантов вы можете создавать свои этапы из нескольких форм. Например, если вы разбиваете карту на две части (с линией, проходящей через каждую фигуру) и создавайте физические тела для этих целей. Затем сделайте их перекрытыми и превратите их в одно тело, тогда это может сработать. Я сделал диаграмму, показывающую это (помилуй его ужасное качество, которое вы все еще можете понять, что он делает (надеюсь)). enter image description here

Другим вариантом было бы сделать это с текстурой, это может немного повредить преформацию, но если вы сможете это сделать, то, вероятно, это будет хорошо работать.

Map.physicsBody = SKPhysicsBody(texture: Map.texture, size: Map.size) 
+0

К сожалению, я абсолютно нужен независимых органов в пределах основной границы. Я подумал об этом, хотя, поскольку это будет работать, если я не смогу найти чистый способ добиться того, что мне нужно :) –

Смежные вопросы