Based on the image below (I used different colours for circle and flat surface so they can be seen, but in the end the colours will be the same), using Swift and Spritekit, I am trying to create the effect of a circular object entering a thick substance (not necessarily sticky) and separating from the thick substance. Basically, when the circular object is separating, it will pull away from the flat surface as it forms into a circle. I wanted to use image animation frames, but since the objects are SKSpriteNodes with physics bodies this will make timing the collision of objects with animation quite difficult. Another approach would be using CAAnimation, but I don't know how this can be combined with SKSpriteNodes with physics bodies. How can I create this separation effect using any of the above stated approaches or a different one?
UPDATE
The image below shows the change in the surface of the thick substance as the circular object enters the thick substance till it's submerged.
This is indeed possible with modern hardware. Let's have a look at what we are going to build here.
In order to achieve that we'll need to
Here's the Molecule class
import SpriteKit class Molecule: SKSpriteNode { init() { let texture = SKTexture(imageNamed: "molecule") super.init(texture: texture, color: .clear, size: texture.size()) let physicsBody = SKPhysicsBody(circleOfRadius: 8) physicsBody.restitution = 0.2 physicsBody.affectedByGravity = true physicsBody.friction = 0 physicsBody.linearDamping = 0.01 physicsBody.angularDamping = 0.01 physicsBody.density = 0.13 self.physicsBody = physicsBody } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
Next we need a Fragment Shader, let's create a file with name Water.fsh
void main() { vec4 current_color = texture2D(u_texture, v_tex_coord); if (current_color.a > 0) { current_color.r = 0.0; current_color.g = 0.57; current_color.b = 0.95; current_color.a = 1.0; } else { current_color.a = 0.0; } gl_FragColor = current_color; }
And finally we can define the scene
import SpriteKit class GameScene: SKScene { lazy var label: SKLabelNode = { return childNode(withName: "label") as! SKLabelNode }() let effectNode = SKEffectNode() override func didMove(to view: SKView) { physicsBody = SKPhysicsBody(edgeLoopFrom: frame) effectNode.shouldEnableEffects = true effectNode.shader = SKShader(fileNamed: "Water") addChild(effectNode) } var touchLocation: CGPoint? override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else { return } let touchLocation = touch.location(in: self) if label.contains(touchLocation) { addRedCircle(location: touchLocation) } else { self.touchLocation = touchLocation } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { touchLocation = nil } override func update(_ currentTime: TimeInterval) { if let touchLocation = touchLocation { let randomizeX = CGFloat(arc4random_uniform(20)) - 10 let randomizedLocation = CGPoint(x: touchLocation.x + randomizeX, y: touchLocation.y) addMolecule(location: randomizedLocation) } } private func addMolecule(location: CGPoint) { let molecule = Molecule() molecule.position = location effectNode.addChild(molecule) } private func addRedCircle(location: CGPoint) { let texture = SKTexture(imageNamed: "circle") let sprite = SKSpriteNode(texture: texture) let physicsBody = SKPhysicsBody(circleOfRadius: texture.size().width / 2) physicsBody.restitution = 0.2 physicsBody.affectedByGravity = true physicsBody.friction = 0.1 physicsBody.linearDamping = 0.1 physicsBody.angularDamping = 0.1 physicsBody.density = 1 sprite.physicsBody = physicsBody sprite.position = location addChild(sprite) } }
The full project is available on my GitHub account https://github.com/lucaangeletti/SpriteKitAqua
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With