Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何防止SKSpriteNode的子级与其父级旋转?_Ios_Rotation_Sprite Kit_Skphysicsbody - Fatal编程技术网

Ios 如何防止SKSpriteNode的子级与其父级旋转?

Ios 如何防止SKSpriteNode的子级与其父级旋转?,ios,rotation,sprite-kit,skphysicsbody,Ios,Rotation,Sprite Kit,Skphysicsbody,我正在使用SpriteKit编写一个iOS游戏,其中包含许多标记球。我通过构建一个包含两个孩子的父SKSpriteNode来构建这些“滚动球”: a) SKShapeNode(实际的圆形状) b) 和一个SKLabelNode(标签) 球将在屏幕上四处移动,在二维空间中相互作用,与其他物体相互作用,完全取决于预期的物理特性(想想台球)。但是如果可能的话,我希望标签不要随父对象旋转,这样它在任何时候都很容易阅读 最简单的方法是什么 标签不应该是容器的子项吗?有没有别的办法把它固定在球形上?或者我可

我正在使用SpriteKit编写一个iOS游戏,其中包含许多标记球。我通过构建一个包含两个孩子的父SKSpriteNode来构建这些“滚动球”:

a) SKShapeNode(实际的圆形状)

b) 和一个SKLabelNode(标签)

球将在屏幕上四处移动,在二维空间中相互作用,与其他物体相互作用,完全取决于预期的物理特性(想想台球)。但是如果可能的话,我希望标签不要随父对象旋转,这样它在任何时候都很容易阅读

最简单的方法是什么

标签不应该是容器的子项吗?有没有别的办法把它固定在球形上?或者我可以在标签上设置一些属性,等等

这是我现在得到的:

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;

一个潜在的超级简单的解决方案:

container.physicsBody.allowsRotation = NO
但这当然会阻止整个精灵旋转。

这似乎有效

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

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

    }];
}

将所有标签放在单个容器中,将标签添加到关联节点的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;
        }
    }
}

请参见

尽管其他解决方案也能起作用,但在使用物理模拟移动节点时,我发现两个节点之间都有一个小间隙

您可以使用两个物理实体并在它们之间添加一个销接头,这样它们将同时更新。我的SKNode子类示例代码(注意:需要将节点添加到场景/节点才能添加关节):


这很奇怪-我在一个刚启动的应用程序中做了完全相同的事情。我只是想以某种方式添加一个销接头,这样标签就固定到父节点上了。hmmm。。这听起来比我下面的解决方案更有希望。。。但是如果标签被固定在父对象上,它不会仍然旋转吗?它会旋转,但是有点独立于父对象物理体,所以你可以调整定位等。我计划我的标签看起来像摩天轮上的马车。大轮子转了一圈,但马车仍然挂在它下面。有趣的是。。。你有没有可能发布或分享一些代码?想知道你到底是怎么做的吗?我还没有尝试过,另一个答案会让它暂时开心。是的,这违背了目的。或者每次都设置zRotation=0。很好。这是计算效率低吗?是的,这对我来说很有效,但我的直觉告诉我还有更好的方法。对于盲目地为所有子节点调整zRotation,我们并不感到激动——我们如何处理具有多个子节点的更复杂的节点,其中一些节点可能仍然希望随容器一起旋转。。。?我喜欢使用SKPhysicsJointPin的想法,但不知道如何使其工作,因为这些管脚固定在场景的坐标系中。我们将暂时将此标记为未答复,看看是否可以获得更多帮助。但是,是的,您的解决方案正在为我的钱包工作,非常感谢。您可以使用node.UserData保存第二位信息,即允许旋转。然后,如果子节点是allow spin,它将旋转,等等。如果您需要帮助,可以更新答案。这会起作用,但从概念上讲,它并不正确。变得越来越复杂,违反了封装最佳实践,你不这么认为吗?真的觉得我们应该能够涉及到实际的物理。而且。。。通过设置扭矩和角度限制,允许标签稍微旋转一点会很好。。。我认为这看起来更现实一些。再次感谢你的帮助。
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];