【问题标题】:Coordinate System in SpriteKitSpriteKit 中的坐标系
【发布时间】:2016-03-08 16:40:31
【问题描述】:

我对 spritekit 坐标系感到很困惑。我需要澄清两种情况。

案例 1:

当精灵节点作为子节点添加到场景中时:

SKSpriteNode * blueBall = [SKSpriteNode spriteNodeWithImageNamed:@"hRedBall.png"];
blueBall.name=@"blueball";
blueBall.size=CGSizeMake(75, 75);
blueBall.position=point; //I am varying this point
[self addChild:blueBall];

我每次都在不同的点添加节点。这些是我添加节点的点:(100x100)(200x200)(300x300)(400x400)(900,600)

在我的 iphone 5 设备中,它们看起来像这样:

如果您查看 100x100,当我在设备上的点 (100,100) 添加精灵时,当我记录节点位置时,它向我显示 (99.9,138.17),这与点 (100,100) 相比存在巨大差异。

尽管其他点也有变化,但我忽略了它们,因为对于其他点来说差异太小了。

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */
      [self bounceTheBlueBallAtPoint:CGPointMake(100, 100)];

}

    -(void)bounceTheBlueBallAtPoint:(CGPoint)point{


    SKSpriteNode * blueBall = [SKSpriteNode spriteNodeWithImageNamed:@"hRedBall.png"];
    blueBall.name=@"blueball";
    blueBall.size=CGSizeMake(75, 75);

    blueBall.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:blueBall.frame.size.width/2];


    blueBall.physicsBody.categoryBitMask=blueBallHitCategory;
    blueBall.physicsBody.collisionBitMask=blueBallHitCategory|pinkBallHitCategory|wallHitCategory;
    blueBall.physicsBody.contactTestBitMask=blueBallHitCategory|pinkBallHitCategory|wallHitCategory;

    blueBall.physicsBody.dynamic=YES;
    blueBall.physicsBody.affectedByGravity=NO;
    blueBall.physicsBody.restitution=1.0;
    blueBall.physicsBody.friction=0.0;
    blueBall.physicsBody.linearDamping=0.0;
    blueBall.physicsBody.angularDamping=0.0;

    blueBall.position=point;

    [self addChild:blueBall];


    //applying impulse to bounce off
//    CGVector impulse = CGVectorMake(30.0,60.0);
//    [blueBall.physicsBody applyImpulse:impulse];
//    

}

我正在用这个方法检查球的位置:

      -(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */

    [self checkSpriteMovement];

   }

    -(void)checkSpriteMovement{

    [self enumerateChildNodesWithName:@"blueball" usingBlock:^(SKNode * _Nonnull node, BOOL * _Nonnull stop) {

        SKSpriteNode *ball=(SKSpriteNode *)node;

        if (ball.physicsBody.resting) {

            NSLog(@"The ball position is %@",NSStringFromCGPoint(ball.position));
        }

    }];

}

案例 2:

假设我有一个背景精灵节点,我将球节点添加到此背景节点,而不是将球节点添加到场景。

 _background = [SKSpriteNode spriteNodeWithImageNamed:@"parkImage.jpg"];
_background.size = self.frame.size; //frame size is (1024x768)
_background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:_background];

然后我将球节点添加到这个背景中:

[_background addChild:blueBall];

这是添加的后台节点:

现在我尝试将球添加到添加的背景中:

在点:(100,100):

点:(-280,-150)

我还想讨论第三种情况:

案例 3:

我想要另一个节点来精灵背景称为环。后来我想将球添加到背景中。所以会有2个子节点。

   _ringNode=[SKSpriteNode spriteNodeWithImageNamed:@"hue_ring.png"];
_ringNode.size=CGSizeMake(80, 80);
_ringNode.position=CGPointMake(0, 0);  //center point of background in this case
_ringNode.anchorPoint=CGPointMake(0.5,0.5);
_ringNode.name=kRingNodeName;
[_background addChild:_ringNode];

所以戒指会在这里:

现在我想将球节点添加到背景节点:

我使用相同的代码将球添加到点 (-280,-150):

为什么场景和精灵节点的坐标系会发生变化?

我面临的另一个问题是:

节点未正确添加到场景中。即使启动了场景,用户也看不到节点,但我可以看到节点数表明屏幕上有节点。我需要运行代码再次查看正确添加到场景中的节点。这种情况每 4 次发生一次。我只需要停止代码并再次运行它以查看碎石上的球,否则我只会看到没有任何球的背景,尽管我正在将它们添加到背景中。

为什么会这样?

我正在添加didMoveToView中的所有节点

【问题讨论】:

  • 请出示案例1的代码
  • 代码添加到案例 1 @trojanfoe
  • 我不认为这是案例 1 的代码。它看起来像案例 2。
  • 我暂时无法发布代码。我远离工作。到家后,我会在 30 分钟内完成。谢谢! :)

标签: ios sprite-kit skspritenode coordinate-systems


【解决方案1】:

好的,所以很难回答这个问题,因为你没有一个问题,但我会尽力解释为什么事情会这样发生。

首先要考虑。您的场景是 1024 x 768(猜测是因为您的一个 cmets 和您的问题)现在这会导致一些问题。首先是你的手机不是那个宽高比,其次你的手机不是那个尺寸。如果您查看您的 ViewController,您可能会看到一些 AspectFill 或 AspectFit 正在设置。这会缩小您的场景。当涉及到您在代码中看到的内容和所做的事情时,事情不再是 1:1 的定位。

让我们走得更远。场景的原点位于左下角,根据您的场景大小和缩放比例,它可能在屏幕外。这是 0,0 所在的位置。因此,您添加的每个孩子都将从那里开始,并根据位置向上和向上工作。 SKSpriteNode 的原点位于中心。例如,您的背景将在中心有一个原点。请注意如何将位置设置为框架宽度和高度的一半。它的原点在中间,您将其向右移动,并从左下角向上移动了正确的距离。现在,当您将子节点添加到该节点时,它会从其父节点的原点开始。在本例中为中心。所以这就是为什么当你将一个球添加到背景时你必须给它负值才能到达左下角。

至于节点没有出现。如果您查看 ViewController,您可能会看到 ignoresSibling 顺序或类似性质的东西。这意味着您必须设置节点的 zPosition。首先渲染较低的 zPosition,因此背景通常为 0,所有显示在背景上方的节点的 zPosition 都为 1 或更高。

希望这会有所帮助。尽管您的问题有据可查,但很难在一个答案中回答所有问题。以后我会建议你分解你的问题并在第一个问题得到回答后提出一个新问题,因为你可能在你有机会问它之前就知道答案=)

【讨论】:

    【解决方案2】:

    案例 1:不知道为什么要扣 38 多分;我需要查看添加节点的代码。

    情况2和3:场景和精灵节点有不同的锚点。 SKScene 是 (0.0, 0.0),SKSpriteNode 是 (0.5, 0.5)。

    【讨论】:

    • 我也添加了案例 1 的代码。如果您查看 didmovetoview 方法,您会发现点 100 ,100
    • 但这是使用物理并将节点添加到后台节点。这不是案例 1 中呈现的内容。我需要确保您在查看当前位置时通过 (100, 100) 并看到 (100, 138)。
    • 我的错,代码是一样的,只是我把-background这一行改成self来添加子节点
    • 我只是在粘贴的代码中更改 [self add child... 行。休息保持不变。我希望这可以澄清案例 1
    猜你喜欢
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多