2013-10-16 5 views
5

SpriteKit을 사용하여 여러 개의 볼이 포함 된 iOS 게임을 작성하고 있습니다. 나는이 아이들과 부모 SKSpriteNode를 구축하여 이러한 'rollingBalls'를 건설하고있어 :SKSpriteNode의 하위 노드가 상위 노드와 함께 회전하지 않도록하려면 어떻게해야합니까?

a)는 SKShapeNode (실제 원형 모양)

B)와 SKLabelNode (라벨)

공 은 화면 전체에서 움직이고, 서로 및 다른 대상과 상호 작용하며, 2 차원으로, 그리고 예상되는 물리학에 전적으로 의존합니다 (당구를 생각하십시오). 그러나 가능한 모든 경우에 라벨을 부모와 함께 회전시키지 않기를 바랍니다. 그래야 항상 쉽게 읽을 수 있습니다.

가장 쉬운 방법은 무엇입니까?

라벨이 컨테이너의 어린이가 아니어야합니까? 공 모양으로 붙일 다른 방법이 있습니까? 아니면 라벨에 설정할 수있는 물건이 있습니까?

여기에 내가 지금 가지고있는 작업은 다음과 같습니다

double ballDiameter = 40; 
UIBezierPath* ovalPath = [UIBezierPath bezierPathWithOvalInRect: 
          CGRectMake(-ballDiameter/2, -ballDiameter/2, 
             ballDiameter, ballDiameter)]; 

SKSpriteNode *container = [[SKSpriteNode alloc]init]; 

container.name = @"rollingBall"; 

SKShapeNode *ballShape = [[SKShapeNode alloc] init]; 
ballShape.path = ovalPath.CGPath; 

SKLabelNode *ballLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"]; 
ballLabel.text = @"some random string"; 
ballLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter; 
ballLabel.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter; 
ballLabel.position = CGPointMake(0,0); 

[container addChild:ballShape]; 
[container addChild:ballLabel]; 

container.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ballDiameter/2]; 
container.physicsBody.usesPreciseCollisionDetection = YES; 
+0

이것은 이상한 일입니다. 앱에서 똑같은 일을하고 있습니다. 나 방금 시작 했어. 어떻게 든 핀 조인트를 추가하기 때문에 레이블이 부모 노드에 보내집니다. – DogCoffee

+0

흠 ...이 아래의 내 솔루션보다 더 유망한 ...하지만 레이블을 부모에게 고정 된 경우 여전히 회전하지 않습니다? – doublea

+0

그것은 회전 할 것이지만, 부모 물리학과는 다소 독립적입니다, 그래서 여러분은 관측 등을 조정할 수 있습니다. 관람차의 캐리지처럼 보이게 할 계획입니다. 큰 바퀴가 돌아 다니지만 캐리지는 그 아래에 매달려 있습니다. – DogCoffee

답변

2

하나의 잠재적 인, 슈퍼 쉬운 솔루션 :

container.physicsBody.allowsRotation = NO 

그러나 물론이 회전에서 전체 스프라이트를 방지 할 수

.

+0

예, 그 목적을 이깁니다. – DogCoffee

5

이 다음 라벨의 위치를 ​​업데이트, 하나의 용기에 라벨을 모두 넣어

-(void) didSimulatePhysics 
{ 
    [self enumerateChildNodesWithName:@"ball" usingBlock:^(SKNode *node, BOOL *stop) { 

     for (SKNode *n in node.children) { 
      n.zRotation = -node.zRotation; 
     } 

    }]; 
} 
+0

또는 매번 zRotation = 0으로 설정하십시오. 잘 작동합니다. 이것은 계산 상 비효율적입니까? – doublea

+0

마이너 업데이트 – DogCoffee

+0

작동하지 않았습니까? – DogCoffee

5

enter image description here

작업 관련 노드의 userData에에 레이블을 추가 할 것으로 보인다.

// Add a container as a scene instance variable. 
SKNode *labels; 

- (void)addLabelContainer 
{ 
    labels = [SKNode node]; 
    [self addChild:labels]; 
} 

- (void)addLabelForNode:(SKNode*)node 
{ 
    SKLabelNode *label = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; 
    node.userData = [NSMutableDictionary dictionaryWithObject:label forKey:@"label"]; 
    label.text = node.name; 
    label.fontSize = 5; 
    label.zPosition = node.zPosition + 1; 
    [labels addChild:label]; 
} 

- (void)removeLabelForNode:(SKNode*)node 
{ 
    [[node.userData objectForKey:@"label"] removeFromParent]; 
    [node.userData removeObjectForKey:@"label"]; 
} 

- (void)update:(NSTimeInterval)currentTime 
{ 
    for (SKNode *node in self.children) { 
     SKNode *label = (SKLabelNode*)[node.userData objectForKey:@"label"]; 
     if (label) { 
      label.position = node.position; 
     } 
    } 
} 

은 다른 솔루션은 잘 작동하지만, 내가 물리 시뮬레이션을 사용하여 이동할 때 두 노드 사이의 작은 차이가 있음을 발견 https://github.com/pmark/MartianRover/blob/master/hiSpeed/hiSpeed/Scenes/LimboScene.m

0

참조하십시오.

두 개의 물리학자를 사용하고 이들 사이에 핀 조인트를 추가하면 이러한 방식으로 동시에 업데이트됩니다. SKNode의 하위 클래스에 대한 샘플 코드 (참고 : 노드를 장면/노드에 추가하여 접합 부분을 추가해야 함) :

SKSpriteNode *overlay = [SKSpriteNode spriteNodeWithImageNamed:@"overlay"]; 
overlay.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:10.0]; 
overlay.allowsRotation = NO; 
[self addChild:overlay]; 

self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:26.0]; 

SKPhysicsJointPin *pinJoint = [SKPhysicsJointPin jointWithBodyA:overlay.physicsBody bodyB:self.physicsBody anchor:self.position]; 
[self.scene.physicsWorld addJoint:pinJoint];