How can I make the intersection of two SKSpriteNodes transparent - ios

I added a background SKSpriteNode as a child to my SKScene. This node itself has some children nodes. Each child has some colored pixels as well as totally transparent pixels. The children nodes are moving across the screen and sometimes intersect each other.
I'd like to make the intersecting colored areas of the children fully transparent as they move so that the background sprite shows through. For the non-intersecting areas of each child, the node should appear as normal. I tried playing around with the blendmode but couldn't get the desired effect. Any ideas how to do this? Or, is there a way to do this outside of SpriteKit?
Thanks

I don't think there are commands to achieve what you want. You can change the the entire texture/image of a sprite, you can change part of a sprite's texture/image appearance by using a filter but you cannot specifically modify part of a sprite's texture/image. To be more specific, a sprite's alpha property applies to the entire sprite and not just part of it.

Related

want SKNode to be semi-transparent to sibling nodes, but opaque to background

I have several SKSpriteNodes that need to be semi-transparent when they intersect each other. If I set the node's color alpha = 0.5 this works as desired. But, I don't want the "background" to show through at all. So the nodes should never blend with the background (ie, the root node).
There is probably a simple technique to accomplish this, but I don't know what it is.
Update
Here is an example of what I'm trying to describe with two simple circle nodes. The circle border has alpha=1.0, the insides are alpha=0.5. As shown the circles blend when overlapped, which is what I want. But then of course they also blend with the background, which is not desired. For the portions that are not overlapped, the inside of the circles should look exactly like the borders.

Spritekit silhouette effect when passing in front of object

I'm working on a sprite kit game and I'm trying to create a particular silhouette lighting effect whenever objects pass in front of a particular object (in this case a red sun). I want anything in front of it to appear black, and everything else to appear as normal (so if an object is partially in front, only that part should be black).
But I'm not sure how to do it in an efficient way. I've tried playing around with different SKBlendModes but so far haven't had much success. The major challenge seems to be achieving the effect whilst preserving the colour of the sun behind.
I'm not sure if it's possible to achieve this with the existing SKBlendModes, or if something else will be required.
I've attached a diagram to illustrate what I'm going for and an image of the current best fit.
You can create the silhouette effect with an SKCropNode, a mask node, and a background node. An SKCropNode selectively mask pixels of the sprite nodes in its node tree. Here, it will provide the silhouette effect by hiding/revealing portions of a black circle.
First, create the following objects:
A shape node (yellow circle) with its zPosition set to -1
A sprite node (black circle) with the same size as the yellow one
A crop node (SKCropNode) and a mask node (SKNode)
Next,
Add the yellow circle at the center of the scene
Add the black sprite as a child of the crop node
Assign the mask node to the maskNode property of the crop node
Add the crop node at the center of the scene
Since the mask node currently has no children, the black circle will be completely hidden and the entire yellow circle beneath it will be visible. As we add sprites to the mask node, the pixels of the black circle that intersect with the sprite will be unmasked (shown in black), producing the silhouette effect.
All that's left is to add a "presentation" node that will be displayed when the mask node's sprite is outside of the black circle. The presentation node will mirror the mask node's sprite's position and rotation. This should be done in didSimulatePhysics to ensure that the presentation and mask-node sprites are synchronized after the physics and actions have been updated.
But wait...if the presentation node moves over the yellow circle, won't it eclipse the Sun? Not if we set its presentation node's zPosition to -2.
The following shows an implementation of the above:
This problem was interesting to me, so I came up with a simple solution. It's not perfect nor does it scale very well, but the basics fulfill your need I believe and it may point others in the right direction.
I don't use any special SKBlendMode. Instead, I am using a duplicate object for the object which moves in front of the sun. This duplicate object is cropped using an SKCropNode with a duplicate of the sun as the maskNode. So, my node tree is as follows:
SKSpriteNode (sun) (the white sun)
SKSpriteNode (object1) (the rotating purple square with alpha 0.25)
SKCropNode
maskNode: SKSpriteNode (sunDuplicate = [sun copy])
SKSpriteNode (object1duplicate, same size as object1 but with [SKColor blackColor])
Inside the update method, align the duplicate with the original to ensure animation is properly forwarded.
- (void)update:(CFTimeInterval)currentTime {
self.object1duplicate.position = self.object1.position;
self.object1duplicate.zRotation = self.object1.zRotation;
}
As I said, this doesn't scale very well since you'll manually have to add duplicate objects and keep track of them for each object moving in front of the sun object. Perhaps SKShader can be of more elegant use.

How to dissolve nodes in SpriteKit?

I have 2 SKSpriteNode objects, and I want to crossfade them.
One of the easiest way is to create a fadeOut SKAction and a fadeIn SKAction, and apply them to the SKSpriteNode objects. But the problem of this approach is that during the action both of them have the alpha under 1.0, which looks not so good.
For example, I'd like to dissolve the red square SKNode to a green round SKNode
If just fade out the red square and fade in the green round during the action it'll look like this
So you can see background through these 2 objects. I hope to dissolve these 2 objects like this:
In UIKit I can use UIView.transitionWithView but in SpriteKit I only found a similar method for presenting scenes (SKViewObject.presentScene: transition:). So is there anyway to make a dissolve transition for SKNodes?
There's little you can about the background coming through when adjusting the alpha settings on both nodes. A possible hack could be to temporarily insert a solid node in front of your background but behind both other nodes until the action is done. At which point you remove it.
The node should be in the shape of both nodes cross-section (pardon the sloppy artwork on my part):
I searched a lot for this question and I nearly decided to use a shader to do this kind of dissolve (since you can directly edit the pixel in a shader), but then I found that there's an unusual way to solve this problem. It may not be useful for every situation, but if your background doesn't do things like scroll or zoom, this approach may be the easiest. In simple words, just create a screenshot for the current screen and display it at the top, then change your node to the sprite you need, and at last fade out the screenshot you took.
So at first you have to make sure all the nodes are in the correct node tree. Then use SKViewObject.textureFromNode(rootNode) to create the screenshot, make a sprite node from this texture, and add it to your screen. Then, you can create the fade out SKAction to fade out this screenshot sprite. You may also remove it when the action ends.
Using this approach, during the fade out the screen will just look like this:

iOS: move circle shape view by collision by dragging another?

I have two UIViews shaped like a circle. (see image).
I am trying to figure out how to make the two views move by collision.
So I am moving one with a touch by changing it's position as I move my finger on it. I want to see the other move as I "push" the one I am moving against the other circle shaped view.
What is the correct way to achieve this?
Using SceneKit did the trick. I created the geometries and then applied physic bodies to each. With the proper physics configuration in the scene they now collide.

How to apply full-screen SKEffectNode for post-processing in SpriteKit

I'm trying out SpriteKit with the following setup:
An SKScene with two child nodes used merely for grouping other
nodes: foreground and background.
background is really empty as of now, but would eventually hold some
type of background sprite / layers.
foreground is a SKEffectNode and whenever the user taps on the
screen, a new intance of a SKnode subclass which represents a game
element is added as child to it.
This SKNode subclass basically creates 3 SKShapeNodes and two labels: an outter
circumference, an inner circumference, 2 labels and an inner quarter circumference. The inner quarter circumference has an SKAction that
makes it rotate forever about its origin / center.
Now here's the issue, as long as foreground doesn't have any CIFilter or has shouldEnableEffects = NO, everything is fine. That is, I can tap on the screen and my game elements are instantiated and added to the main scene. But the minute I try adding a CIGaussianBlur or CIBloom to the foreground, I notice two things:
The framerate drops to about 2fps. Mind you, this happens even with
as little as 6 nodes alive in the scene.
The effect seems to be constantly cropping its contents or adjusting
it's frame. That is, if I have one node, the "full screen" effect
seems to try and constantly crop or adjust its bounds to the minimum
area required to hold all nodes. This is for one node:
And this is for 2 nodes:
In OpenGL ES 2, one would do a post blur / bloom by basically rendering the whole framebuffer (all objects) to texture, then doing at least one more pass to blur,etc on that texture and then either present that in the framebuffer attached to the display or compose that with the original render back to the framebuffer. I'd expect SKEffectNode to work in a similar way. However the cropping and the poor performance makes me think I might be using the effect node the wrong way. Any thoughts?
It seems to be a bug with the SKEffectNode trying to apply a filter on children SKShapeNodes as far as I can tell. I played around with this and achieved your results, but when I switched out the SKShapeNodes for SKSpriteNodes (using a simple png of a circle) the cropping no longer appears. It's a bug in that SKEffectNode doesn't handle the stroke of the SKShapeNode very well. If you take off the stroke (lineWidth = 0) and give it a fill color, you'll see that there is no cropping.
As for the frame rate, SKShapeNodes perform poorly. Doing the switch to SKSpriteNodes I mentioned earlier boosted my fps from 40 to 50 when I had 35 nodes on the screen (iPhone 5) with the filter applied.

Resources