iOS 使用 CAEmitterLayer 创建落叶动画
iOS create falling leaves animations using CAEmitterLayer
我想制作树叶飘落的动画这是我的代码:
private func setupEmitter() {
let size = self.bounds.size
let emitter = CAEmitterLayer()
emitter.emitterSize = CGSize(width: size.width, height: 1)
emitter.emitterPosition = CGPoint(x: size.width / 2, y: -100)
emitter.emitterShape = kCAEmitterLayerLine
self.layer.addSublayer(emitter)
//SHAPE 1
let shape1 = CAEmitterCell()
shape1.birthRate = 10
shape1.lifetime = 7
shape1.lifetimeRange = 2
shape1.velocity = 110
shape1.velocityRange = 10
shape1.emissionLongitude = CGFloat(M_PI)
shape1.emissionRange = CGFloat(M_PI_4)
shape1.spin = 0.2
shape1.spinRange = 0
shape1.scaleSpeed = -0.05
shape1.scale = -0.3
shape1.scaleRange = -0.1
shape1.contents = UIImage(named: "shape1")?.cgImage
//SHAPE 2
let shape2 = CAEmitterCell()
shape2.birthRate = 10
shape2.lifetime = 7
shape2.lifetimeRange = 2
shape2.velocity = 110
shape2.velocityRange = 90
shape2.emissionLongitude = CGFloat(M_PI)
shape2.emissionRange = CGFloat(M_PI_4)
shape2.spin = 0.2
shape2.spinRange = 0.5
shape2.scaleSpeed = -0.05
shape2.scale = -0.35
shape2.scaleRange = 0
shape2.contents = UIImage(named: "shape2")?.cgImage
emitter.emitterCells = [shape1, shape2]
}
我从上面的代码中得到了什么:
我想达到的效果图:
那么我怎样才能更新我的代码来实现我想要的(Objective-C 代码被接受)?
不幸的是,这并不容易,也不简单,我也不能简单地说 "here's the code that does this!"
实现目标的方法有多种,none 其中比较理想,但都以不同的方式棘手。
叶子的这些运动,当它们向下飘动时,它们是否达到了它们在空气动力学上变得有效的速度,停滞然后再次下降......它要么是你需要的物理系统,要么是编码为对速率响应的行为坠落。
物理学:
核心动画粒子没有足够的物理响应来执行此操作,因此您需要使用受力和场组合影响的 SKSpriteNodes
,或受 [= 影响的 CALayers
12=] 力和场的变化。
这两个东西几乎相同:CALayers
是 SKSpriteNodes
的更强大和有趣的变体,UIKit Dynamics
与 SKPhysics
非常相似。
但是......如果你想走这条路,构建你自己的 'particle' 系统来响应力和场,我强烈建议使用 SceneKit 的粒子,因为它们具有旋转(在 3D 中) 内置的粒子能力,它是一个在处理许多不同的粒子发射器时非常有效的系统,每个粒子发射器都有自己的响应场。
算法上:
这涉及到创建弧线的随机化到失速,然后加速到另一个向下的弧线,空气动力学影响,以及随后的失速,一遍又一遍。
这也需要自定义粒子,因为我认为没有一种方法可以充分直接影响 CAEmitter 粒子,也没有 SpriteKit 或 SceneKit 的粒子。
这意味着您必须在 OpenGL 中创建四边形、作为树叶简单图像的 CALayer、作为树叶的 SKSpriteNodes,或者在 SceneKit 中创建具有树叶纹理的四边形。
在每种情况下,您需要的图层或对象与您需要的叶子一样多。
CALayers 的优点是内置了 3D 旋转,你似乎已经对 Core Animation 有了一定的掌握。
我想制作树叶飘落的动画这是我的代码:
private func setupEmitter() {
let size = self.bounds.size
let emitter = CAEmitterLayer()
emitter.emitterSize = CGSize(width: size.width, height: 1)
emitter.emitterPosition = CGPoint(x: size.width / 2, y: -100)
emitter.emitterShape = kCAEmitterLayerLine
self.layer.addSublayer(emitter)
//SHAPE 1
let shape1 = CAEmitterCell()
shape1.birthRate = 10
shape1.lifetime = 7
shape1.lifetimeRange = 2
shape1.velocity = 110
shape1.velocityRange = 10
shape1.emissionLongitude = CGFloat(M_PI)
shape1.emissionRange = CGFloat(M_PI_4)
shape1.spin = 0.2
shape1.spinRange = 0
shape1.scaleSpeed = -0.05
shape1.scale = -0.3
shape1.scaleRange = -0.1
shape1.contents = UIImage(named: "shape1")?.cgImage
//SHAPE 2
let shape2 = CAEmitterCell()
shape2.birthRate = 10
shape2.lifetime = 7
shape2.lifetimeRange = 2
shape2.velocity = 110
shape2.velocityRange = 90
shape2.emissionLongitude = CGFloat(M_PI)
shape2.emissionRange = CGFloat(M_PI_4)
shape2.spin = 0.2
shape2.spinRange = 0.5
shape2.scaleSpeed = -0.05
shape2.scale = -0.35
shape2.scaleRange = 0
shape2.contents = UIImage(named: "shape2")?.cgImage
emitter.emitterCells = [shape1, shape2]
}
我从上面的代码中得到了什么:
我想达到的效果图:
那么我怎样才能更新我的代码来实现我想要的(Objective-C 代码被接受)?
不幸的是,这并不容易,也不简单,我也不能简单地说 "here's the code that does this!"
实现目标的方法有多种,none 其中比较理想,但都以不同的方式棘手。
叶子的这些运动,当它们向下飘动时,它们是否达到了它们在空气动力学上变得有效的速度,停滞然后再次下降......它要么是你需要的物理系统,要么是编码为对速率响应的行为坠落。
物理学:
核心动画粒子没有足够的物理响应来执行此操作,因此您需要使用受力和场组合影响的 SKSpriteNodes
,或受 [= 影响的 CALayers
12=] 力和场的变化。
这两个东西几乎相同:CALayers
是 SKSpriteNodes
的更强大和有趣的变体,UIKit Dynamics
与 SKPhysics
非常相似。
但是......如果你想走这条路,构建你自己的 'particle' 系统来响应力和场,我强烈建议使用 SceneKit 的粒子,因为它们具有旋转(在 3D 中) 内置的粒子能力,它是一个在处理许多不同的粒子发射器时非常有效的系统,每个粒子发射器都有自己的响应场。
算法上:
这涉及到创建弧线的随机化到失速,然后加速到另一个向下的弧线,空气动力学影响,以及随后的失速,一遍又一遍。
这也需要自定义粒子,因为我认为没有一种方法可以充分直接影响 CAEmitter 粒子,也没有 SpriteKit 或 SceneKit 的粒子。
这意味着您必须在 OpenGL 中创建四边形、作为树叶简单图像的 CALayer、作为树叶的 SKSpriteNodes,或者在 SceneKit 中创建具有树叶纹理的四边形。
在每种情况下,您需要的图层或对象与您需要的叶子一样多。
CALayers 的优点是内置了 3D 旋转,你似乎已经对 Core Animation 有了一定的掌握。