在 SpriteKit 中使用 UIInterpolatingMotionEffect?
Use UIInterpolatingMotionEffect in SpriteKit?
UIInterpolatingMotionEffect 旨在与 UIView 一起使用,但是否有可能在节点上的 SpriteKit 中使用它?
如果没有,有人有想法用另一种方式实现效果吗?
提前致谢
在 Sprite Kit 中创建视差效果可以通过以下方式实现:创建一组 SKNode
图层,向图层添加 sprite,然后在用户倾斜设备时将每个图层移动不同的量。您可以选择缩放图层以产生深度错觉。
这是 Swift 中的一个实现。由于它使用加速度计,因此只能在设备(而不是模拟器)上使用。
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
}
}
UIInterpolatingMotionEffect 旨在与 UIView 一起使用,但是否有可能在节点上的 SpriteKit 中使用它?
如果没有,有人有想法用另一种方式实现效果吗?
提前致谢
在 Sprite Kit 中创建视差效果可以通过以下方式实现:创建一组 SKNode
图层,向图层添加 sprite,然后在用户倾斜设备时将每个图层移动不同的量。您可以选择缩放图层以产生深度错觉。
这是 Swift 中的一个实现。由于它使用加速度计,因此只能在设备(而不是模拟器)上使用。
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
}
}