Is there a way to make a skspritenode move in a certain direction? As in degrees. EG: Face 70˚ then move in that direction. I am trying to make it so you can shoot a bullet from my player node but I cant figure out how to make the bullet go past where my mouse is.
if you're using physics, then you can applyImpulse using a CGVector. If you're not using physics then you would use an SKAction, but it doesn't solve your specific use. If you wanted to rotate the object first, then you'd change its zRotation. Obviously you'd have to setup the sprite and the physicsBody, but I've left those steps out.
SKSpriteNode *mySpriteToMove = [SKSpriteNode node];
[mySpriteToMove.physicsBody applyImpulse:CGVectorMake(floatDX, floatDY)];
[mySpriteToMove runAction:[SKAction moveBy:CGVectorMake(floatDX, floatDY) duration:amountOfTime]];
mySpriteToMove.zRotation = someValueInRadians;
CODE FOR COMMENT RESPONSE:
[mySpriteToMove runAction:[SKAction moveTo:CGPointMake(floatX, floatY) duration:amountOfTime]];
Related
I'm working on a basic game for micro:bit just as a way to learn the technology, and I was hoping that one of the sprites would move in the direction of the compass.
Is there a way to do this?
Use the "set" block to set the direction of the sprite to "compass heading (º)", then "move" the sprite a number of steps (in that direction). It might also be good to add "if on edge, bounce" block.
Thank you #neillb!
I've been looking for a solution for quite a while now, but I can't help finding one. The situation is as following: I created an SKSpriteNode with an image, by the method touchesBegan I want to interact with it, like if one touches the image, something should change. The problem is that the hitbox around this image is square-shaped and not adjusted to the shape of the image. Has anyone got any clue how I can solve this problem? I tried doing it by changing the physicsBody like this
CGFloat offsetX = node.frame.size.width * node.anchorPoint.x;
CGFloat offsetY = node.frame.size.height * node.anchorPoint.y;
CGMutablePathRef path = CGPathCreateMutable();
CGPathCloseSubpath(path);
node.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
Seems like the touchesBegan method doesn't use the physicsBody shape but the actual shape, I tried my best explaining it, sorry if I confused you.
Thanks in advance!
Julian
In the Xcode level editor, under the physics definition of your SKSpriteNode, change the body type to alpha mask (see image). This makes the physics boundary conform to the actual shape of your sprite rather than the rectangular bounding box.
Sadly, this solution only applies if your sprites are managed in an .sks file since level editor seems to have logic that calculates your sprite's outline and turns it into a path used to initialize the physics body with a body type of 'alpha mask'. (Too bad there's currently no 'bodyType' property on SKPhysicsBody because it would be really convenient to be able to set this programmatically instead of only being able to do so in the .sks file... Apple?)
The way you're attempting to create and initialize an SKPhysicsBody with a CGpath is on the right track I think... But since it's currently an empty path (having no points or lines) I'm guessing it won't have any effect.
Is there any way you could approximate some points & lines to represent a rough outline path for your sprite? Then, you could use those points to create a CGPath and then use that to initialize an SKPhysicsBody.
If not, a short-term compromise could be to initialize your SKPhysicsBody using init(circleOfRadius:) and use a circle as the body type which could seem less clunky than a box. And you could maybe play around with the circle radius to get a feel for the most natural radius for your collisions.
How would I use sprite kit physics in my endless runner game?
An endless runner fakes motion by keeping the player stationary but moving the background and all the other objects by a set speed.
BUT, I want to simulate physics.
What if I let my player move with the physics engine, move the background by the displacement of the player from the original position, and then move the player back to it's original position?
Would this be smooth and look good? If so, then what methods of sprite kit do I use so no visual errors show to the user.
What's the proper solution?
Thank you.
The proper way is to center the scene on a node. The best way to learn how to do so is to go ahead and visit the docs here (go to section titled 'Centering Scene on a Node'), but if you encounter any problems with the implementation let us know!
In case you're wondering how it works, the background stays stationary (unless you want parallax scrolling), while the character moves. However, every frame the camera 'follows' a player, meaning wherever you moved your player with the physics, the screen will follow and keep the character at the center.
Edit
Here is the code I use in one of my games to center on the sprite (which is a plane controlled by buttons):
-(void)didSimulatePhysics {
... #Code here to simulate plane movement and such
SKNode *camera = [self childNodeWithName:#"//camera"];
SKNode *player = [self childNodeWithName:#"//sprite"];
if (player.position.y >= 0) camera.position = CGPointMake(player.position.x, player.position.y);
else camera.position = CGPointMake(player.position.x, 0);
[self centerOnNode:camera];
if (velocity>1){
self.directionMeter.zRotation = -M_PI/2 + mdirectionOfTravel;
}
}
-(void)centerOnNode:(SKNode *)node {
CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
node.parent.position = CGPointMake(node.parent.position.x - cameraPositionInScene.x, node.parent.position.y - cameraPositionInScene.y);
}
Basically, when the player is above a certain position, I move the camera up with the player. When the player moves anywhere on the x-axis, the camera always moves with them. I have contact detection to find where the player hits the ground (and thus loses), and the background color (the sky) changes according to the altitude of the plane (the higher the plane, the darker the blue).
I'm doing a simple game in SpriteKit, and have little problem. I would like my character/player(SKSpriteNode) to rotate himself to position where I touched the screen, so he always face touched to coordinates. I know there something like zRoatation, but I don't know how to calculate an angle. I will be really grateful for any tips.
I found a answer thanks to Antoine Lecaille.
float newAngle = -atan2(newPosition.x - currentPosition.x, newPosition.y -currentPosition.y) + [self degToRad:180];
In my game, I have a CCSprite that orbits another CCSprite, much like an electron orbiting a nucleus. I have the electron as a child of the nucleus, to make animation much simpler. All I have to do is rotate the nucleus and the electron follows suite quite nicely.
However, my problem comes from wanting to have the orbit animation appear a little snazzier, by either adding something like a particle system trail, or a ribbon effect following the path of the electron. I cannot simply add a particle system to the electron itself, because the particles don't follow correctly, since they are being rotated by the nucleus as well. If I add the particle system to self, then they appear correctly, but not in the same position as the object they are supposed to be trailing.
My question is this:
Is there a way to get the scene position of an object, say the electron, as opposed to only having access to it's position relative to it's parent?
Thanks.
Yes there is!
Each CCNode and its descendants has the ability to get a position relative to the scene:
CGPoint worldCoord = [mySprite convertToWorldSpace: mySprite.position];
This worldCoordinate will be relative to the scene as opposed to the parent node!
Hope this helped! ^_^
A later edit:
When you do:
[aSprite convertToWorldSpace:position];
You are actually getting the global coordinates of position in aSprite's coordinate system. If you want to translate aSprite's position to global space you need to ask for it's parent to do the translation for you, because the sprite.position is already in it's parents coordinates system.
Hope it explains it
Original Answer:
For me this solution did not work
I had a 2 level hierarchy where mySprite is a child of a CCSprite that is a child of the scene.
Bottom line: This code fixed the problem for me:
CGPoint worldCoord = [[mySprite parent]convertToWorldSpace: mySprite.position];
This is the hierarchy structure that required my solution:
myScene -> mySpriteParent -> mySprite
mySprite.position:29,254
mySpriteParent.position:533,57
Solution1 - wrong result:
[mySprite convertToWorldSpace: mySprite.position]:91,418
Solution2 - right result:
[[boxSprite parent] convertToWorldSpace:boxSprite.position]:253.5,275.5
Perhaps this solution will help someone
And maybe someone will explain why this solution works and not the other