2013-10-16 6 views
5

Ich benutze SpriteKit, um ein iOS-Spiel zu schreiben, das eine Anzahl beschrifteter Bälle beinhaltet. Ich bin die Konstruktion dieses 'rollingBalls' durch einen Elternteil SKSpriteNode mit 2 Kindern Aufbau:Wie kann ich verhindern, dass sich das Kind eines SKSpriteNode mit seinem Elternteil dreht?

a) ein SKShapeNode (die tatsächliche Kreisform)

b) und ein SKLabelNode (das Label)

Die Kugeln werden sich über den gesamten Bildschirm bewegen, miteinander und mit anderen Objekten interagieren, in zwei Dimensionen, und vollständig abhängig von der erwarteten Physik (denke Billard). Aber wenn es mir möglich ist, möchte ich, dass das Etikett NICHT mit dem Elternteil rotiert, so dass es jederzeit gut lesbar bleibt.

Was ist der einfachste Weg, dies zu tun?

Sollte das Etikett kein Kind des Containers sein? Gibt es eine andere Möglichkeit, es an die ballShape zu hängen? Oder gibt es eine Eigenschaft, die ich auf dem Etikett usw. einstellen kann?

Hier ist, was ich jetzt habe:

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

das ist seltsam - ich bin in einer App, die genau die gleiche Sache zu tun Ich habe gerade angefangen. Ich werde nur irgendwie eine Stiftverbindung hinzufügen, also wird das Etikett an den Elternknoten gebunden. – DogCoffee

+0

hmmm .. das hört sich vielversprechender an als meine Lösung unten ... aber wenn das Etikett an den Elternteil angeheftet ist, wird es sich dann noch drehen? – doublea

+0

wird es Spin sein, aber ein wenig unabhängig von der Physik der Elternkörper, so können Sie die Positionierung usw. optimieren. Ich plane für meinen, wie eine Kutsche auf einem Riesenrad zu erscheinen. Das große Rad läuft herum, aber der Wagen bleibt darunter hängen. – DogCoffee

Antwort

2

Ein Potential, super einfache Lösung:

container.physicsBody.allowsRotation = NO 

Aber natürlich wird dies den gesamten Sprit nicht drehen.

+0

Ja, das den Zweck besiegt. – DogCoffee

5

Dies scheint

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

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

    }]; 
} 
+0

oder setzen Sie zRotation = 0 jedes Mal. funktioniert gut. ist das rechnerisch ineffizient? – doublea

+0

hat kleinere Aktualisierung – DogCoffee

+0

aint es funktioniert? – DogCoffee

5

enter image description here

alle Etiketten in einem einzigen Behälter Stoßen, fügen Sie das Etikett auf die zugeordneten Knotens Userdata, dann aktualisieren Label Positionen zu arbeiten.

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

Siehe https://github.com/pmark/MartianRover/blob/master/hiSpeed/hiSpeed/Scenes/LimboScene.m

0

Obwohl die anderen Lösungen als auch arbeiten, ich festgestellt, dass beide Knoten einen kleinen Spalt zwischen ihnen haben, wenn sie mit der Physik-Simulation zu bewegen.

Sie können 2 Physikkörper verwenden und eine Stiftverbindung zwischen ihnen hinzufügen, auf diese Weise werden sie gleichzeitig aktualisiert. Mein Beispielcode für eine Unterklasse von SKNode (Anmerkung: Sie müssen den Knoten zu einer Szene/Knoten hinzugefügt haben, einen gemeinsamen hinzugefügt werden):

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]; 
Verwandte Themen