天天看點

iOS 動畫二十四:粒子系統 Particle Emitters

瀑布,火焰,煙霧和雨水效果都涉及大量的粒子 - 它們具有共同的實體特征,也具有自己獨特的尺寸,方向,旋轉和軌迹。

粒子可以很好地建立逼真的效果,因為每個粒子都可以是随機的和不可預測的。 例如,暴風雨中的每個雨滴可能具有獨特的大小,形狀和速度。

iOS 粒子系統有以下幾種常用發射類型:

1. Point shape

kCAEmitterLayerPoint 的發射器形狀會導緻所有粒子在同一點建立。 對于涉及煙花的效果,這是一個很好的選擇。我們可以通過在同一點建立粒子并在它們消失之前使它們沿不同方向飛行來建立煙花效果。

2. Line shape

這是一種用于瀑布效果的發射器形狀; 水粒子出現在瀑布的頂部邊緣并向下級聯:

3. Rectangle shape

kCAEmitterLayerRectangle 的發射器形狀通過給定的矩形區域随機建立粒子:

這種發射器形狀非常适合許多不同的效果,例如碳酸飲料中的氣泡。

除了以上幾種類型,還有 cuboid, circle and sphere 等發射類型。欲知更多,請查閱相關資料。

Particle Emitters 相關屬性設定:

1. Adding an emitter frame

emitter.emitterPosition = CGPoint(x: rect.width/2, y: rect.height/2)
 emitter.emitterSize = rect.size
複制代碼
           

結合形狀,位置和尺寸屬性定義發射器架構。 這裡,可以将發射器的位置設定為圖層的中心,并将發射器大小設定為等于圖層的大小。like so:

2. Creating an emitter cell

emitter cell 是表示一個粒子源的資料模型,它與 CAEmitterLayer 是不同的類,單個 emitter layer 可以包含一個或多個 cells。

例如,在爆米花動畫中,可以有三個不同的 cells 來代表爆米花核心的不同狀态:完全爆開、半爆開和那些頑固的未爆開:

粒子發射器示例:

3. Controlling your particles

// add a little acceleration in the y-direction so the particles will drift downwards like real snow.
    emitterCell.yAcceleration = 70.0
    // snowflakes should be moving in a downward diagonal direction
    emitterCell.xAcceleration = 10.0
    emitterCell.velocity = 20.0 
    emitterCell.emissionLongitude = .pi * -0.5
複制代碼
           

發射經度 emissionLongitude 是粒子的初始角度,velocity 參數設定粒子的初始速度,如下所示:

4. Adding randomness to your particles

設定發射器随機範圍:

emitterCell.velocityRange = 200.0
複制代碼
           

每個粒子的速度将是(20-200)= -180 和(20 + 200)之間的随機值。 初始速度為負的粒子根本不會上升,一旦它們出現在螢幕上,它們就會開始向下移動。 具有正速度的粒子則将首先向上移動,然後向下移動。

emitterCell.emissionRange = .pi * 0.5
複制代碼
           

確定所有粒子在出現時以-π/ 2角度直接向上發射。上面的代碼訓示發射器在(-π/ 2 - π/ 2)= 180度和(-π/ 2 +π/ 2)= 0 度範圍内為每個粒子挑選一個随機角度,如下圖所示:

5. Changing particle color

emitterCell.color = UIColor(red: 0.9, green: 1.0, blue: 1.0, alpha: 1.0).cgColor

// 顔色範圍
emitterCell.redRange = 0.3 
emitterCell.greenRange = 0.3 
emitterCell.blueRange = 0.3
複制代碼
           

綠色和藍色分量值現在是 0.7 到 1.3 之間的随機值,但是,高于 1.0 的值的上限為 1.0,是以有效範圍為 0.7 到 1.0。 紅色成分,因為其 “normal” 值為 0.9,是以它的上限介于 0.6 和 1.0 之間。 這些是相對較窄的範圍,是以産生的随機顔色看上去差異不大。

6. Randomizing particle appearance

emitterCell.scale = 0.8 
emitterCell.scaleRange = 0.8
複制代碼
           

這樣可以産生大到比原始尺寸大 1.6 倍的大雪花,小到零尺寸的雪花。

emitterCell.scaleSpeed = -0.15
複制代碼
           

訓示粒子按每秒 15% 比例縮小。 當雪花接近螢幕的下半部分時,雪花會越來越小。 這是一個很 nice 的效果。

emitterCell.alphaRange = 0.75 
emitterCell.alphaSpeed = -0.15
複制代碼
           

設定一個寬的 alpha 範圍,從 0.25 到 1.0 。 alphaSpeed與 scaleSpeed 非常相似,可以随時間更改粒子的 alpha 值。

7. Adding some final polish

emitterCell.emissionLongitude = -.pi
複制代碼
           

發射經度 emissionLongitude 是發射粒子的起始角。 初始角度改為 -.pi 角度,會讓雪花有像被風吹動的效果。

附:主要代碼:

// creates a new CAEmitterLayer, sets the layers’ frame to take up the full width of the screen and positions the layer near the top of the screen.
    let rect = CGRect(x: 0.0, y: -70.0, width: view.bounds.width, height: 50.0)
    let emitter = CAEmitterLayer()
    emitter.frame = rect
    view.layer.addSublayer(emitter)
    
    // The shape of your emitter generally affects the area where new particles are being created
    emitter.emitterShape = kCAEmitterLayerRectangle
    
    emitter.emitterPosition = CGPoint(x: rect.width/2, y: rect.height/2)
    emitter.emitterSize = rect.size
    
    // create a new cell and set flake.png as its contents. The contents property holds the template from which new particles will be created.
    let emitterCell = CAEmitterCell()
    emitterCell.contents = UIImage(named: "flake.png")?.cgImage

    // 每秒建立 20 個雪花,并将它們保持在螢幕上 3.5 秒。 這意味着除了動畫的最初幾秒,在任何給定時間螢幕上将有 70 個雪花。 
    emitterCell.birthRate = 20
    emitterCell.lifetime = 3.5

    // add a little acceleration in the y-direction so the particles will drift downwards like real snow.
    emitterCell.yAcceleration = 70.0
    // snowflakes should be moving in a downward diagonal direction
    emitterCell.xAcceleration = 10.0
    emitterCell.velocity = 20.0
    emitterCell.emissionLongitude = .pi * -0.5
    
    emitterCell.velocityRange = 200.0
    emitterCell.emissionRange = .pi * 0.5
    emitterCell.color = UIColor(red: 0.9, green: 1.0, blue: 1.0, alpha: 1.0).cgColor
    emitterCell.redRange = 0.1
    emitterCell.greenRange = 0.1
    emitterCell.blueRange = 0.1
    
    emitterCell.scale = 0.8
    emitterCell.scaleRange = 0.8
    
    emitterCell.scaleSpeed = -0.15// The scaleSpeed property above instructs your particles to scale down by 15% of their original size per second
    
    emitterCell.alphaRange = 0.75
    emitterCell.alphaSpeed = -0.15
    
    emitterCell.emissionLongitude = -.pi

    // 因為 emitterCell.lifetime = 3.5,lifetimeRange = 1.0 将每個雪的生命周期設定為 2.5 到 4.5 秒之間的随機值。
    emitterCell.lifetimeRange = 1.0

    
    //cell #2
    let cell2 = CAEmitterCell()
    cell2.contents = UIImage(named: "flake2.png")?.cgImage
    cell2.birthRate = 50
    cell2.lifetime = 2.5
    cell2.lifetimeRange = 1.0
    cell2.yAcceleration = 50
    cell2.xAcceleration = 50
    cell2.velocity = 80
    cell2.emissionLongitude = .pi
    cell2.velocityRange = 20
    cell2.emissionRange = .pi * 0.25
    cell2.scale = 0.8
    cell2.scaleRange = 0.2
    cell2.scaleSpeed = -0.1
    cell2.alphaRange = 0.35
    cell2.alphaSpeed = -0.15
    cell2.spin = .pi
    cell2.spinRange = .pi
    
    //cell #3
    let cell3 = CAEmitterCell()
    cell3.contents = UIImage(named: "flake3.png")?.cgImage
    cell3.birthRate = 20
    cell3.lifetime = 7.5
    cell3.lifetimeRange = 1.0
    cell3.yAcceleration = 20
    cell3.xAcceleration = 10
    cell3.velocity = 40
    cell3.emissionLongitude = .pi
    cell3.velocityRange = 50
    cell3.emissionRange = .pi * 0.25
    cell3.scale = 0.8
    cell3.scaleRange = 0.2
    cell3.scaleSpeed = -0.05
    cell3.alphaRange = 0.5
    cell3.alphaSpeed = -0.05
    
    emitter.emitterCells = [emitterCell, cell2, cell3]
複制代碼
           

demo下載下傳

轉載于:https://juejin.im/post/5c419a46e51d457d1b7f3aaa