I have following hierarchy:
Scene -> Root node -> NodeA -> NodeB (anchor node that's rotated) -> NodeC
how can I figure out visual position of NodeC in Root node coordinate space?
I've tried several variants with convertPoint:toNode: and convertPoint:fromNode: but numbers i'm getting don't match.
I've also looked at Get visible location of SpriteKit node after parent rotation, which seems to be close to my issue, but no luck there either.
Found what I was missing - convertToPoint needs to be called from the node in which final CGPoint value will be represented in. So, this works:
// point is CGPointZero because it is center of NodeC
let point = rootNode.convertPoint(CGPointZero, fromNode: NodeC) as CGPoint!
Related
I am currently working at a 2D endless runner in SpriteKit. I create new Level sequences using the Scene Editor and then add them as a SKReferenceNode to the main scene.
The problem is, that I need to get the position of the single nodes inside of the SKReferenceNode, but the ones I get, are relative to the SKReferenceNodes coordinate system and not the main one.
How can I get the position of the nodes relative to the main scene?
you'll want to use the convert func
func convert(_ point: CGPoint, to node: SKNode) -> CGPoint
Description
Converts a point in this node’s coordinate system to the coordinate system of another node in the node tree.
Parameters
point - A point in this node’s coordinate system.
node - Another node in the same node tree as this node.
Returns
The same point converted to the other node’s coordinate system.
above x, y, z is root node.
I want to know when root node is shown
how to show/hide root node on screen.
Thank you
You can't ever 'show the node', but you can attach objects to the node and visualise those, as you have done (with the lines).
If you want to see the actual point that the node is at, you can attach a SCNSphere (or any geometry).
let sphere = SCNSphere(radius: CGFloat(0.02))
sphere.firstMaterial?.diffuse.contents = UIColor.magenta
var node = SCNNode(geometry: sphere)
As an aside, you can make the node visible / invisible using node.isHidden = true etc. This will hide the node, any attached geometry, and all of its children nodes.
I'm making my first shooter game using Swift and SpriteKit and I've recently been running into problems with setScale(). I have a Laser class whose instances are added as children to a Ship class. I now realize that any down scaling of the parent node will scale its child as well. In my update method in GameScene I check the position of each child named 'Laser' to determine if it should be removed from its parent when offscreen. I recently updated some of my sprites- including their relative sizes, and I noticed that the position of each laser is way off, as they are removed far before they reach the end of the screen and upon debugging their x positions are in fact far larger than where they are displayed onscreen. I also noticed that the starting x of each Laser instance is relative to its original position within the Ship instance. So the ship may be halfway across the screen but the laser x position still starts at 0 and if the ship is able to pass the laser, the laser's position becomes negative--is there a way to grab its position on the screen rather than relative to its start within its parent?
This is the code I'm doing the check with:
self.aShip.gun.enumerateChildNodesWithName("laser",
usingBlock: { node, _ in
if let aLaser = node as? Laser { i
if(aLaser.position.x > self.size.width){
aLaser.removeFromParent()
}
}
}
)
It seems like scaling has a ton more baggage than I would normally assume, so any insight into this problem or how to manage the relation between code and sprites would be awesome!!
EDIT:
I found that adding let positionInScene = self.convertPoint(aLaser.position, fromNode: self.aShip.gun) under if let aLaser = node as? Laser {and consequently using positionInScene rather than the aLaser position works.. however, I still don't fully understand the scaling effect going on with aLaser and it's position and don't know if its efficient to have to convert positions like this at the rate of update (60 times a second).
I want to add SKShapeNode to random position, using Sprite Kit, until the screen getting full.
How can I find the empty space in screen?
This is not an off the shelf kind of function in SK. Your only solution would be to create a hack to do what you want. One possible approach might be to create a very small node and place it in various positions on the screen, using a loop. For example (x,y position), 0,0 -> 4,0 -> 8,0 and so on...
You can use the func intersectsNode(_ node: SKNode) -> Bool to see if this node intersects any other node.
Another approach might be to use the same kind of logic but use func containsPoint(_ p: CGPoint) -> Bool instead.
Both approaches would be processor intensive so you should only run them sparingly.
First post,
I'm in Apple's SpriteKit framework...(new programmer) and I have a bunch of nodes that are stationary. How do I select/grab a particular node if I know the coordinates (CGPoints)? I basically want to say, grab that node at (x,y) and do something with it (i.e. change color)
Thanks
If you know the CGPoint, you use the command nodeAtPoint: However, this command only returns the deepest descendant that intersects a point. If you have the possibility of having more than one node at your CGPoint, you should use the command nodesAtPoint: instead.
Read up on the details in the SKNode Class Reference - section titled Determining If a Point Lies in a Node.
** Update **
CGPoint myPoint = CGPointMake(10, 10);
SKNode *myNode = [self nodeAtPoint:myPoint];
Where self either is or needs to be replaced with the parent node of the node you are looking for.