5

SpriteKit を使用して、多数のラベル付きボールを含む iOS ゲームを作成しています。2 つの子を持つ親 SKSpriteNode を構築することで、これらの「rollingBalls」を構築しています。

a) SKShapeNode (実際の円形状)

b) および SKLabelNode (ラベル)

ボールは画面全体を移動し、互いに相互作用し、他のオブジェクトと 2 次元で相互作用し、予想される物理 (ビリヤードを考えてください) に完全に依存します。しかし、可能であれば、いつでも簡単に読めるように、ラベルを親と一緒に回転させないようにしたいと思います。

これを行う最も簡単な方法は何ですか?

ラベルはコンテナーの子であってはなりませんか? それを ballShape にペグする他の方法はありますか? または、ラベルなどに設定できるプロパティはありますか?

これが私が今持っているものです:

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;
4

4 に答える 4

6

ここに画像の説明を入力

すべてのラベルを 1 つのコンテナーに配置し、関連するノードの 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を参照してください。

于 2014-04-10T21:41:07.497 に答える
1

考えられる非常に簡単な解決策の 1 つ:

container.physicsBody.allowsRotation = NO

しかしもちろん、これはスプライト全体が回転するのを防ぎます。

于 2013-10-16T21:36:13.417 に答える
0

他のソリューションも同様に機能しますが、物理シミュレーションを使用してノードを移動すると、両方のノード間に小さなギャップがあることがわかりました。

2 つの物理ボディを使用して、それらの間にピン ジョイントを追加すると、同時に更新されます。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];
于 2015-07-11T18:31:38.527 に答える