UIInterpolatingMotionEffect is intended for use with UIView, but is there a possibility to use it within SpriteKit on a node ?
If not, does someone has an idea to realize the effect another way.
Thanks in advance
UIInterpolatingMotionEffect is intended for use with UIView, but is there a possibility to use it within SpriteKit on a node ?
If not, does someone has an idea to realize the effect another way.
Thanks in advance
Creating a parallax effect in Sprite Kit can be achieved by creating a set of SKNode
layers, adding sprites to the layers, and then moving each layer by a different amount when the user tilts the device. You can optionally scale the layers to give the illusion of depth.
Here's an implementation in Swift. Since it uses the accelerometer, this will only work on a device (not the Simulator).
import SpriteKit
import CoreMotion
class GameScene: SKScene {
let squareSize = CGFloat(50.0)
let manager = CMMotionManager()
let maxDistance = CGFloat(40.0)
override func didMoveToView(view: SKView) {
let colors = [SKColor.redColor(), SKColor.greenColor(), SKColor.blueColor()]
for i in 0..<colors.count {
let node = createLayer(colors[i], depth: CGFloat(colors.count-i), screenSize: view.frame.size)
addChild(node)
}
var tiltX:CGFloat = 0.0
var alpha:CGFloat = 0.25
// Define block to handle accelerometer updates
if manager.accelerometerAvailable {
manager.accelerometerUpdateInterval = 0.1
manager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
[weak self] (data: CMAccelerometerData!, error: NSError!) in
// Low-pass filter to smooth the measurements
tiltX = tiltX * (1-alpha) + CGFloat(data.acceleration.x) * alpha
for (index, node) in enumerate(self!.children as! [SKNode]) {
// Move each layer by a different amount to produce parallax effect
let deltaX = tiltX*CGFloat(index+1)*self!.maxDistance
node.position = CGPoint(x:self!.size.width/2.0+deltaX, y:self!.size.height/2.0)
}
}
}
}
func createLayer(color:SKColor, depth:CGFloat, screenSize:CGSize) -> SKNode {
let scale = 1.0/depth
let node = SKNode()
// Scale layer to create depth effect
node.setScale(scale)
node.zPosition = -depth
node.position = CGPoint(x:screenSize.width/2.0, y:screenSize.height/2.0)
let size = CGSize(width: squareSize, height: squareSize)
// Create squares at random positions
for i in 1...10 {
let square = SKSpriteNode(color: color, size: size)
let x = CGFloat(arc4random_uniform(UInt32(screenSize.width))) - screenSize.width / 2.0
let y = CGFloat(arc4random_uniform(UInt32(screenSize.height))) - screenSize.height / 2.0
square.position = CGPoint(x:x, y:y)
node.addChild(square)
}
return node
}
}