我們常見的一些像下雪讲婚、下雨尿孔、火苗這類的動畫,都是可以使用粒子效果來實現(xiàn)筹麸。主要使用了類CAEmitterLayer
和CAEmitterCell
來實現(xiàn)活合。下面我們將通過實現(xiàn)一個下雪的效果來說明該類的使用方法和各個屬性的含義。
CAEmitterLayer 可理解為粒子發(fā)射器
創(chuàng)建一個CAEmitterLayer
的實例物赶,也就是創(chuàng)建一個發(fā)射器白指。
CGRect rect = CGRectMake(0, 100, self.view.bounds.size.width, 50);
//創(chuàng)建發(fā)射器
CAEmitterLayer *emitter = [CAEmitterLayer layer];
emitter.frame = rect;
[self.view.layer addSublayer:emitter];
設(shè)置發(fā)射器類型
//設(shè)置發(fā)射器類型
emitter.emitterShape = kCAEmitterLayerRectangle;
這時候就要說一下屬性emitterShape
的取值了。有6種取值kCAEmitterLayerPoint
酵紫、kCAEmitterLayerLine
告嘲、kCAEmitterLayerRectangle
错维、kCAEmitterLayerCuboid
、kCAEmitterLayerCircle
和kCAEmitterLayerSphere
橄唬。簡單介紹幾種
- kCAEmitterLayerPoint 設(shè)置為該類型赋焕,發(fā)射器的所有粒子都將從一個相同的點創(chuàng)建。這個點是發(fā)射器的position仰楚。
- kCAEmitterLayerLine 設(shè)置為該值隆判,所有粒子都將在發(fā)射器最上端的創(chuàng)建。
- kCAEmitterLayerRectangle 設(shè)置為該值僧界,所有粒子都在發(fā)射器的整個區(qū)域創(chuàng)建侨嘀。
其他三種先不說了。
需要注意的捂襟,上述所說的區(qū)域不是emitterLayer的咬腕,而是由屬性emitterPosition
和emitterSize
來確認(rèn)的。
下面就來設(shè)置這兩個屬性的值笆豁,在該例子中郎汪,將其設(shè)置為和layer一樣了。
emitter.emitterPosition = CGPointMake(rect.size.width*0.5, rect.size.height*0.5);
emitter.emitterSize = rect.size;
CAEmitterCell 可理解為我們要發(fā)射的例子
和我們之前說過的Animation一樣闯狱,CAEmitterCell也只不過是我們?yōu)槟阌脕碚宫F(xiàn)粒子形態(tài)的一個數(shù)據(jù)模型煞赢。
我們創(chuàng)建一個粒子,并且將圖片flake.png作為其內(nèi)容哄孤。接下來發(fā)射器會創(chuàng)建他的很多各種各樣的拷貝來模擬真實的雪花照筑。
CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];
emitterCell.contents = (__bridge id _Nullable)([UIImage imageNamed:@"flake"].CGImage);
接著添加代碼
//設(shè)置粒子創(chuàng)建速率,也就是每秒產(chǎn)生的個數(shù)
emitterCell.birthRate = 20;
//設(shè)置粒子的生命周期瘦陈,也就是在屏幕上存在的時間
emitterCell.lifetime = 3.5;
//將粒子賦給發(fā)射器
emitter.emitterCells = @[emitterCell];
需要解釋的是emitterCells屬性凝危。我們將emitterCells屬性設(shè)置為一個存放著CAEmitterCell類型數(shù)據(jù)的數(shù)組。同一個發(fā)射器是可以發(fā)射不同類型的粒子的晨逝。
這回運(yùn)行程序蛾默,我們將看到這樣的效果
我們發(fā)現(xiàn)雖然產(chǎn)生了粒子,但是他們并不會運(yùn)動捉貌。所以支鸡,繼續(xù)努力
添加代碼
//設(shè)置粒子創(chuàng)建速率,也就是每秒產(chǎn)生的個數(shù)
emitterCell.birthRate = 200;
//設(shè)置粒子的生命周期趁窃,也就是在屏幕上存在的時間
emitterCell.lifetime = 3.5;
//設(shè)置粒子聲明周期范圍
emitterCell.lifetimeRange = 1.0;
//將粒子賦給發(fā)射器
emitter.emitterCells = @[emitterCell];
//設(shè)置y軸上的加速度
emitterCell.yAcceleration = 70.0f;
//設(shè)置x軸上的加速度
emitterCell.xAcceleration = 10.0f;
//設(shè)置粒子的初始速度
emitterCell.velocity = 20;
//設(shè)置粒子的初始角度 如果不設(shè)置這個值牧挣,我們發(fā)現(xiàn)粒子都是水平發(fā)射的
emitterCell.emissionLongitude = -M_PI_2;
//設(shè)置粒子的初始速度范圍 在此例子中范圍是 -180~220
emitterCell.velocityRange = 200.0f;
//設(shè)置粒子的初始角度范圍 此例子的范圍為 M_PI~0
emitterCell.emissionRange = M_PI_2;
//設(shè)置粒子的顏色
emitterCell.color = [UIColor colorWithRed:0.9 green:1.0 blue:1.0 alpha:1.0].CGColor;
//我們也可以設(shè)置隨機(jī)顏色,并且限定范圍醒陆。因為RGB的值最大為1.0,那Red來說瀑构,范圍并不會變?yōu)?.6~1.3,而是0.6~1.0。相似的刨摩,如果是負(fù)值寺晌,則最小為0
emitterCell.redRange = 0.3;
emitterCell.greenRange = 0.3;
emitterCell.blueRange = 0.3;
//設(shè)置粒子的大小及其大小范圍
emitterCell.scale = 0.8;
emitterCell.scaleRange = 0.8;
//設(shè)置讓粒子隨著時間推移每秒減小15%,如果設(shè)置為正值則每秒增加
emitterCell.scaleSpeed = -0.15;
//設(shè)置粒子透明度的變化范圍
emitterCell.alphaRange = 0.75;
//設(shè)置粒子變化速度
emitterCell.alphaSpeed = -0.15;
好多屬性都是有range相關(guān)的類型世吨,都是指定的范圍,沒有一個個的寫折剃。
最終效果: