
1 .粒子發(fā)射器: CAEmitterLayer
CAEmitterLayer是核心動畫中的一個類,用它可以很原生的創(chuàng)造微粒效果.每一個微粒就是一個CAEmitterCell對象,我們可以不用太過關(guān)心cell的創(chuàng)建與銷毀.只要我們設(shè)置好參數(shù),這些系統(tǒng)會幫我們完成.
話不多說,上代碼:
// 創(chuàng)建CAEmitterLayer 并設(shè)置好CAEmitterLayer
let emitter = CAEmitterLayer()
let rect = CGRect(x: 0.0, y: 100.0, width: view.bounds.width, height: 100)
emitter.backgroundColor = UIColor.blackColor().CGColor
emitter.frame = rect
view.layer.addSublayer(emitter)
// 所有粒子隨機(jī)出現(xiàn)在所給定的矩形框內(nèi)
emitter.emitterShape = kCAEmitterLayerRectangle
// 設(shè)置位置大小
emitter.emitterPosition = CGPoint(x: rect.width/2, y: rect.height/2)
emitter.emitterSize = rect.size
// 一個cell代表一個微粒
let emitterCell = CAEmitterCell()
emitterCell.contents = UIImage(named: "flake")!.CGImage
// 每秒出現(xiàn)的比率 cell的生命周期
emitterCell.birthRate = 8
emitterCell.lifetime = 3
emitter.emitterCells = [emitterCell]

emitter的emitterShape屬性:
常用到的有三種:
- kCAEmitterLayerPoint 將所有的粒子集中在position的位置,可用來做火花爆炸效果
- kCAEmitterLayerLine 所有的粒子位于一條線上,可用來作瀑布效果,下雪效果
- kCAEmitterLayerRectangle 所有粒子隨機(jī)出現(xiàn)在所給定的矩形框內(nèi)
在上面代碼的基礎(chǔ)上,在添加下面的:
// x y 軸的加速度
emitterCell.yAcceleration = 70.0
emitterCell.xAcceleration = 70.0
// 初始速度
emitterCell.velocity = 20.0
// 發(fā)射角度
emitterCell.emissionLatitude = CGFloat(M_PI_2)

上面的CAEmitterLayer設(shè)置的屬性基本都是固定的值,如果我們要實現(xiàn)一個下雪效果,需要很多隨機(jī)的屬性,這些都有:
func snow() {
// 通過CAEmitterLayer可以很原生的創(chuàng)造微粒效果,不需要第三方庫
let emitter = CAEmitterLayer()
let rect = CGRect(x: 0.0, y: -100.0, width: view.bounds.width, height: view.bounds.height+100)
// let rect = view.bounds
emitter.backgroundColor = UIColor.blackColor().CGColor
emitter.frame = rect
view.layer.addSublayer(emitter)
// kCAEmitterLayerPoint 將所有的粒子集中在position的位置,可用來做火花爆炸效果
// kCAEmitterLayerLine 所有的粒子位于一條線上,可用來作瀑布效果
// kCAEmitterLayerRectangle 所有粒子隨機(jī)出現(xiàn)在所給定的矩形框內(nèi)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterPosition = CGPoint(x: rect.width/2, y: 0)
emitter.emitterSize = rect.size
// 一個cell代表一個微粒
let emitterCell = CAEmitterCell()
emitterCell.contents = UIImage(named: "flake3")!.CGImage
// 每秒創(chuàng)建的cell
emitterCell.birthRate = 250
// cell的生命周期為1.5秒
// emitterCell.lifetime = 10
// emitter可以添加很多不同類型的cell
emitter.emitterCells = [emitterCell]
// 制造一個y軸的加速度
emitterCell.yAcceleration = 70.0
// 制造一個x軸的加速度
emitterCell.xAcceleration = 10.0
// emitterCell.velocity = 20.0
// 給微粒設(shè)置一個發(fā)射角度
emitterCell.emissionLongitude = CGFloat(-M_PI)
// emitterCell.scale = 0.8
// 添加隨機(jī)的速度,如果有velocity,那么范圍為 -180 ~ 220
emitterCell.velocityRange = 200.0
emitterCell.emissionRange = CGFloat(M_PI_2)
emitterCell.lifetimeRange = 18
// emitterCell.color = UIColor(red: 0.9, green: 1.0, blue: 1.0, alpha: 1.0).CGColor
// 值為0.3 的范圍為 0.7~1.3,但由于高于1算1,所以值得范圍為 0.7~1
emitterCell.redRange = 0.3
emitterCell.greenRange = 0.3
emitterCell.blueRange = 0.3
// 隨機(jī)大小
emitterCell.scaleRange = 0.8
// 每秒縮小15%
emitterCell.scaleSpeed = -0.05
emitterCell.alphaRange = 0.75
emitterCell.alphaSpeed = -0.15
}

2.幀動畫
其實iOS上所有的動畫,到最后都是轉(zhuǎn)化成已幀動畫的形式播放的.當(dāng)然了,這種幀動畫的實現(xiàn)肯定也會提供的.
實現(xiàn)的步驟:
// 將需要添加幀動畫的圖片添加進(jìn)去
penguinView.animationImages = walkFrames
// 設(shè)置播放時間
penguinView.animationDuration = animationDuration / 3
// 設(shè)置重復(fù)次數(shù)
penguinView.animationRepeatCount = 3
// 最后在一個適當(dāng)?shù)奈恢貌シ啪托辛? penguinView.startAnimating()
幀動畫我們實現(xiàn)一個小企鵝可以左右行走,并且可以在地上滑動的效果:
注:由于比較簡單,我就簡單的貼一下代碼啦!想細(xì)看的可以找文章末尾給出的源碼鏈接!
1.添加背景圖片,以及左右移動,以及滑動按鈕,并設(shè)置好按鈕的監(jiān)聽
// MARK: - 設(shè)置UI
lazy var bgView : UIImageView = {
let bgView = UIImageView(image:UIImage(named: "bg"))
bgView.frame = self.view.bounds
return bgView
}()
lazy var leftButton : UIButton = {
let btn = UIButton()
btn.setImage(UIImage(named: "btn-left"), forState: .Normal)
btn.frame = CGRect(x: 0, y: UIScreen.mainScreen().bounds.height-100, width: 100, height: 100)
btn.addTarget(self, action: Selector("leftBtnClick"), forControlEvents: .TouchUpInside)
return btn
}()
lazy var rightButton : UIButton = {
let btn = UIButton()
btn.setImage(UIImage(named: "btn-right"), forState: .Normal)
btn.frame = CGRect(x: 100, y: UIScreen.mainScreen().bounds.height-100, width: 100, height: 100)
btn.addTarget(self, action: Selector("rightBtnClick"), forControlEvents: .TouchUpInside)
return btn
}()
lazy var slideButton : UIButton = {
let btn = UIButton()
btn.setImage(UIImage(named: "btn-slide"), forState: .Normal)
btn.frame = CGRect(x: UIScreen.mainScreen().bounds.width-100, y: UIScreen.mainScreen().bounds.height-100, width: 100, height: 100)
btn.addTarget(self, action: Selector("slideBtnClick"), forControlEvents: .TouchUpInside)
return btn
}()
lazy var penguinView : UIImageView = {
let penguin = UIImageView()
penguin.image = UIImage(named: "walk01")
penguin.frame = CGRect(x: 100, y: UIScreen.mainScreen().bounds.height-175, width: self.penguinWidth , height: 96)
return penguin
}()
2.加載幀動畫圖片,設(shè)置好走路和滑行的動畫,判斷是否需要翻轉(zhuǎn)圖片
// 添加走路動畫的圖片
var walkFrames = [
UIImage(named: "walk01.png")!,
UIImage(named: "walk02.png")!,
UIImage(named: "walk03.png")!,
UIImage(named: "walk04.png")!
]
// 添加滑行的圖片
var slideFrames = [
UIImage(named: "slide01.png")!,
UIImage(named: "slide02.png")!,
UIImage(named: "slide01.png")!
]
let animationDuration = 1.0
let penguinWidth: CGFloat = 108.0
let penguinHeight: CGFloat = 96.0
// 走路的動畫
func loadWalkAnimation() {
// 將需要添加幀動畫的圖片添加進(jìn)去
penguinView.animationImages = walkFrames
// 設(shè)置播放時間
penguinView.animationDuration = animationDuration / 3
// 設(shè)置重復(fù)次數(shù)
penguinView.animationRepeatCount = 3
}
// 滑行的動畫
func loadSlideAnimation() {
penguinView.animationImages = slideFrames
penguinView.animationDuration = animationDuration
penguinView.animationRepeatCount = 1
}
// 判斷左右 如果不是右邊翻轉(zhuǎn)圖片
var isLookingRight: Bool = true {
didSet {
let xScale: CGFloat = isLookingRight ? 1 : -1
penguinView.transform = CGAffineTransformMakeScale(xScale, 1)
slideButton.transform = penguinView.transform
}
}
3.處理按鈕的點擊事件
func leftBtnClick() {
isLookingRight = false
penguinView.startAnimating()
UIView.animateWithDuration(animationDuration, delay: 0.0, options: .CurveEaseOut, animations: {
self.penguinView.center.x -= self.penguinWidth
}, completion: nil)
}
func rightBtnClick() {
isLookingRight = true
penguinView.startAnimating()
UIView.animateWithDuration(animationDuration, delay: 0.0, options: .CurveEaseOut, animations: {
self.penguinView.center.x += self.penguinWidth
}, completion: nil)
}
func slideBtnClick() {
// 設(shè)置滑行動畫
loadSlideAnimation()
penguinView.startAnimating()
UIView.animateWithDuration(animationDuration - 0.02, delay: 0.0, options: .CurveEaseOut, animations: {
self.penguinView.center.x += self.isLookingRight ?
self.penguinWidth : -self.penguinWidth
}, completion: {_ in
self.loadWalkAnimation()
})
}

總結(jié):本篇主要介紹了粒子效果,以及幀動畫.
本文整理自 : iOS.Animations.by.Tutorials.v2.0
源碼 : https://github.com/DarielChen/DemoCode
如有疑問,歡迎留言 :-D