iOS動畫指南 - 5.下雪的粒子效果、幀動畫

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容