Search code examples
sprite-kitskspritenodecgpathcgpathref

SKSprite not positioning where it should


I've got a character in a game, and it's supposed to shoot a bullet. I've set everything up for the character, and have setup the path for the bullet to travel through. Here's the code I'm using:

//The destination of the bullet
int x = myCharacter.position.x - 1000 * sin(myCharacter.zRotation);
int y = myCharacter.position.y + 1000 * cos(myCharacter.zRotation);


//The line to test the path
SKShapeNode* beam1 = [SKShapeNode node];

//The path
CGMutablePathRef pathToDraw = CGPathCreateMutable();

//The starting position for the path (i.e. the bullet)
//The NozzleLocation is the location of the nozzle on my character Sprite
CGPoint nozzleLoc=[self convertPoint:myCharacter.nozzleLocation fromNode:myCharacter];
CGPathMoveToPoint(pathToDraw, NULL, nozzleLoc.x, nozzleLoc.y);
CGPathAddLineToPoint(pathToDraw, NULL, x, y);

//The bullet
SKSpriteNode *bullet = [SKSpriteNode spriteNodeWithTexture:bulletTexture size:CGSizeMake(6.f, 6.f)];
bullet.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:3 center:bullet.position ];
[bullet.physicsBody setAffectedByGravity:NO];
[bullet.physicsBody setAllowsRotation:YES];
[bullet.physicsBody setDynamic:YES];
bullet.physicsBody.categoryBitMask = bulletCategory;
bullet.physicsBody.contactTestBitMask = boundsCategory;

//These log the correct locations for the character
//and the nozzle Location
NSLog(@"myposition: %@",NSStringFromCGPoint(myCharacter.position));
NSLog(@"nozloc: %@",NSStringFromCGPoint(nozzleLoc));

bullet.position = [bullet convertPoint:nozzleLoc fromNode:self];
[self addChild:bullet];
NSLog(@"Bullet Position: %@",NSStringFromCGPoint(bullet.position));
[bullet runAction:[SKAction followPath:pathToDraw duration:6.f]];

//I'm using this to test the path
beam1.path = pathToDraw;
[beam1 setStrokeColor:[UIColor redColor]];
[beam1 setName:@"RayBeam"];
[self addChild:beam1];

This is what I get from the NSLogs I'm using above:

myposition: {122.58448028564453, 109.20420074462891}

nozloc: {145.24272155761719, 77.654090881347656}

Bullet Position: {145.24272155761719, 77.654090881347656}

So everything should work, right? But the issue that I'm having is that the bullets are shot from a slightly different location. You can see from the image below:

enter image description here

I aligned the character, so that the bullets start from that little square in the middle. This way you can see the distance from where the bullet are supposed to start (in front of the gun my character is holding), and the square in the middle of the screen.

The bullets travel correctly on a straight line, and the angle of the line is the same as the angel of the path ( the path and the line bullets form are parallel as you can see from the picture). When I move my line, the bullets also move in the same way. I think the issue is the point conversion between nodes, but I've tried both

[self convertPoint:myCharacter.nozzleLocation fromNode:myCharacter]
[bullet convertPoint:nozzleLoc fromNode: self]
[self convertPoint:nozzleLoc toNode:bullet]

However, they all result in the exact same starting point for the bullet. Do you know why I'm having this issue? Is it because I'm scaling down my character sprite using setScale (I'm setting it to 0.3)?

Thanks a lot in advance for your help.


Solution

  • This isn't your issue but nozzleLoc is already in the scene's coordinate space so it should be:

    bullet.position = nozzleLoc;
    

    This will save a quick second conversion from having to be calculated.

    followPath:duration: is the same as followPath:asOffset:orientToPath:duration: with asOffset: YES -- it's using your current position as the origin of the path. See the documentation here.

    To fix it you'll want the asOffset to be NO (requires the full method call above) or you can leave it as is and take out the line of code setting the bullet's position.