Can you mask an SKSpriteNode with another SKSpriteNode - swift

Just ask the title asks, I am wondering if this is at all possible. Most examples of the SKCropNode use a texture or a shape. What I want to accomplish is a mask of a custom shape. Let me know if there's a way!

You could mask a node by giving it a child node where the child node's zPosition is greater than the parent's. And then, of course, you'd have to position the child node correctly on top of the parent node -but this should be easy as the child node's position is located relative to the parent node (i.e. if parent has position (25, 30) in the scene, and you set child.position = CGPoint(x:5, y:0), the child's position in the scene would be (30, 30)). Also, if the parent node moves, the child node moves with it.

Related

Need to SCNNode within restricted area

I have created a SCNNode object on a SCNPlane object. Both objects are added to the scene view root node, like below:
scView.scene.rootNode.addChildNode(ballNode)
scView.scene.rootNode.addChildNode(planeNode)
Now, my issue is that the ball node is moving out of the plane node boundary.
When I tried to add ballNode as planeNode's child then, the ball node is not getting added to a plane as expected. It behaves very strangely.
Basically, I need to restrict the movement of ballNode within planeNode area. How can I do it?
Great question!
When adding a child node to another node, there are no constraints being implicitly applied to the child, aside from existing within the infinite coordinate space of the parent node.
While changing the transform (eg position) of the parent node will directly apply to all child nodes, each child node can still freely transform within the parent nodes local coordinate space.
It'd be a good idea to read the SCNNode docs if you haven't already, as it covers the foundational aspects.
To do what you want, when moving the ball in your gameloop, you will need to manually check whether or not that ball is outside the boundary you are trying to enforce, and change its position accordingly.
Depending on your desired outcome, you may want to also check out SCNPhysicsBody as a way to construct your scene with implied physical boundaries.

Swift SceneKit issue with node position on preview

I'm trying to add nodes to my scene view, but all of the nodes have a zero position, but different placements.
Each node has a position (0,0,0) but, on the scene view, this node has a different placement. Also, I can`t find the distance between nodes because each node has a position (0, 0, 0). Please explain to me what is wrong with my nodes.
If you want to fetch the real position of a node try this:
node.presentation.worldPosition
This should always return you the effective position of the node as seen on screen.
The problem was in 3d object, the original position of the 3d was not centered. I upload each 3c object to Blender and change original position to (0,0,0)

High SpriteKit draw count with SKSpriteNode & texture atlas

I have a SpriteKit game in which there are balls that bounce around. Despite using a texture atlas (a .spriteatlas folder located in my .xcassets folder), I'm getting 2 draw calls for each ball.
Some facts:
The balls are SKSpriteNode's.
Each ball is a parent node that has a child node (an overlay with the opposite rotation of the ball to provide the illusion of lighting/shadow). So, we're talking about 2 nodes for each ball.
The balls' textures are preloaded up front and stored in memory via textureNamed(_:).
I have set view.ignoresSiblingOrder = true.
There is no SpriteKit background image that would make the balls render on top of another node; the background is transparent. So, the balls do not overlap other content.
zPosition is not set -- not on the parent and not on the child.
Based on what I've learned about how the scene is rendered, I would expect to see all the parent nodes rendered in a single pass, with additional passes for the child nodes (though, even that is suspicious since I have ignoresSiblingOrder set to true).
What am I not understanding, here? Why does my draw count increase so drastically as more balls are added to the scene?
Thank you!
UPDATE:
If I don't add the child nodes to the balls, the draw count for the balls is 1 regardless of how many balls there are. So, it's definitely an issue with the child nodes, not the parents.
I solved the problem by setting zPosition to the same value on both the parent and child.
parentNode.zPosition = 1.0
childNode.zPosition = 1.0
There are now a total of 2 draws for the balls regardless of how many balls there are.

Swift SpriteKit: Flipping parent sprite randomizes child nodes horizontal alignment

I have a parent SKSpriteNode which contains a number of child SKShapeNodes, SKSpriteNodes and SKLabelNodes arranged in specific X,Y position relative to the parent.
When I flip the parent by running an SKAction on it:
SKAction.scaleXTo(-1, duration: duration)
It flips the parent including the children (which I want) but the horizontal alignment of all the children nodes is randomized.
I must mention that I have
parent.anchorPoint = CGPoint(x: 0,y: 0)
The reason this is happening is because of your anchor point. Scaling (And all transformations) happens on this point. To test, take a piece of paper, put a pencil on the top left corner, then try moving the right side over to the left. leaving the pencil where it is. You will notice that the right side is now -width of the paper
What you need to do in this case, is add the width back in to keep the paper at the same location.
Same rule with the sprites. You have to add the width in when doing a negative scale, then remove the width when going back to a positive scale
(or just put your anchor in the center)
Geometrical transformation you apply to a node are automatically applied to its descendants.
This is why when you move/rotate/scale a node the children (and the grandchildren...) are updated as well.
If you want apply a transformation to your sprite without involving other nodes simply change the structure of you scene moving the children of your sprite like shown below.
As it is now
In this image the green circle is your sprite. In the left scenario when you change the green node, it's children are updated accordingly. And you don't want that.
As it should be
So move to the right scenario. Create a new SKNode (the orange one) and place it as shown below.
Now the green node has no children so you can apply geometrical transformation to it without any side effect.

Make a SKLabelNode in spritekit appear above all other sprites

Hi im pretty new to programming and I have encountered a small issue. I am creating a simple game which has a score label. However, the score label is covered whenever a downward scrolling obstacle passes. I would like for the score label to not be covered by the obstacles.Is there a way i can change the sprite hierarchy in spritekit? Thanks
I would recommend creating a node for the static stuff that should be fixed on screen (like a game HUD). Then you set this node's zPosition to be higher then the game play node (where all game objects are placed and manipulated).
This makes it also easier implementing a camera or moving the game play node if needed without the score label or any other fixed hud element moving as well.
So you will have something like this :
SKNode *hudNode = [SKNode node];
hudNode.zPosition = 1000;
[hudNode addChild:scoreLabel];
SKNode *gamePlayNode = [SKNode node];
gamePlayNode.zPosition = 0; // Not mandatory as it defaults to 0 but I put this here for clarification
[self addChild:hudNode]; // self is your scene instance
[self addChild:gamePlayNode];
You can change the zPosition property of your label node, by making it 100 it will be above all other nodes (default value is 0.0):
labelNode.zPosition = 100;
Nodes are drawn in the order they are added to the scene (or parent node). You can change the order in which nodes are drawn by setting their zPosition property.
From Apple's documentation...
...The z position is the node’s height relative to its parent node, much as a node’s position
property represents its x and y position relative to parent’s
position. So you use the z position to place a node above or below the
parent’s position.
When you take z positions into account, here is how the node tree is
rendered:
Each node’s global z position is calculated.
Nodes are drawn in order from smallest z value to largest z value.
If two nodes share the same z value, ancestors are rendered first, and siblings are rendered in child order.
You can also use zPosition to optimize rendering performance...
...it might be better if Sprite Kit could gather all of the nodes that share the same texture and drawing mode and and draw them with a single drawing pass. To enable these sorts of optimizations, you set the view’s ignoresSiblingOrder property to YES.