Coordinate System in SpriteKit

断了今生、忘了曾经 提交于 2020-01-13 19:41:35

问题


I am quite confused with the spritekit coordinate system. I need clarification on two cases.

Case 1:

When a sprite node is added as child to the scene:

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

I have added the node at different points each time.These are the points I added the node at: (100x100)(200x200)(300x300)(400x400)(900,600)

And in my iphone 5 device, they look like this:

If you look into 100x100, when I add the sprite at point (100,100), on device, when I log the node position, it showed me (99.9,138.17) which is huge difference compared to the point (100,100).

Even though there are changes in the other points too, I neglect them as the difference is way too small for other points.

-(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];
//    

}

I am checking the ball position in this method:

      -(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));
        }

    }];

}

Case 2:

Let's say I have a background sprite node, and I add the ball node to this background node instead of adding the ball node to scene.

 _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];

and then I add the ball node to this background:

[_background addChild:blueBall];

This is the background node added:

Now I tried to add ball to the added background:

At point:(100,100):

At point:(-280,-150)

I would also like to discuss the third case:

Case 3:

I want to another node to sprite backgorund called ring. And later I want to add ball to the background. So there will be 2 child nodes.

   _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];

so the ring will be here:

And now I want to add ball node to the background node:

I used the same code to add the ball at point (-280,-150):

Why is there the change in coordinate system of scene and sprite nodes?

Another issue I am facing is:

The nodes are not added to scene properly.Even though the scene is launched, the nodes are not visible to user, but I can see the node count which says that there are nodes on the screen.I need to run the code again to see the nodes added correctly to the scene. This is happening once in every 4 times. I just need to stop the code and run it again to see the balls on the scree, else I see just the background without any balls though I am adding them to background.

Why is this happening?

I am adding all the nodes in didMoveToView


回答1:


Ok so it is going to be tough to answer this because it isn't like you have one question but I will do my best to explain why things are happening the way they are.

First thing to think about. Your Scene is 1024 x 768 (guessing that because of one of your comments and because of your problem) Now this causes a few issues. First being your phone isn't that aspect ratio second your phone isn't that size. If you look at your ViewController you will likely see some AspectFill or AspectFit being set. This scales down your scene. Things are no longer 1:1 for positioning when it comes to what you see and what you do in code.

Lets go further. The Scene's origin is in the bottom left and depending on your scene size and scaling it may be off screen. This is where 0,0 is. So every child you add will start there and work its way right and up based on position. A SKSpriteNode has its origin in the center. Your background for example would have an origin in the center. Notice how you set the position to half the frames width and height. Its origin is in the middle and you moved it over to the right and up the correct distance form the bottom left. Now when you add a child node to that node it starts from the origin of its parent. In this example the center. So that is why you have to give it negative values to get down to the bottom left when you add a ball to the background.

As far as nodes not showing up. If you look in your ViewController you will likely see ignoresSibling order or something to that nature. This means you have to set the zPosition of your nodes. Lower zPositions get rendered first so background is usually 0 and all nodes to show above background get a zPosition of 1 or higher.

Hopefully that helps. Although your questions are well documented it makes it very difficult to answer all your questions in one answer. In the future I would recommend breaking your questions up and asking a new question after the first one gets answered because you may learn the answer before you even have a chance to ask it =)




回答2:


Case 1: No idea why it's 38-odd points off; I need to see the code that adds the nodes.

Cases 2 and 3: The scene and the sprite node have different anchor points. For SKScene it's (0.0, 0.0) and for SKSpriteNode it's (0.5, 0.5).



来源:https://stackoverflow.com/questions/34076632/coordinate-system-in-spritekit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!