本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看。
我们经常在电视屏幕中可以看到爆炸,雨滴和烟雾等特效。这一节的动画特效,就是介绍如何在移动设备上实现类似的效果。
瀑布流,火,烟和雨滴等效果都是由很多的项组成的,我们称之为 "颗粒"。颗粒可以仿真出真实的效果,因为每一个颗粒可以是随机的并且是不可预测的。例如:在风暴中的每一个雨滴有他们自己的尺寸,方向等因素。
下图就是大家经常可以看到的颗粒发射器的效果图:
在本节中,我要讲解的是 "雪花飘落" 的效果。最终效果图如下:
下面,我们就来分析怎样实现的这样的效果。
1. 创建发射器图层
要实现这样的效果,我们可以借助于CAEmitterLayer, 你可以在Core Animation中借助它来实现颗粒效果。
1) 创建CAEmitterLayer
CGRect rect = CGRectMake(0, 100, self.view.frame.size.width, 50.0);
CAEmitterLayer *emitter = [CAEmitterLayer layer];
emitter.backgroundColor = [UIColor greenColor].CGColor;
emitter.frame = rect;
[self.view.layer addSublayer:emitter];
2) 定义发射器的发射形态
emitter.emitterShape = kCAEmitterLayerRectangle;
Extension:
常用的发射形态有三种:
A: Point shape
KCAEmitterLayerPoint 这种发射形态可以促使所有的颗粒都聚集于一点(即发射器的position所在处),使用它可以实现火花或者烟火的效果,示意图如下:
B: Line shape
KCAEmitterLayerLine 这种发射形态可以促使所有的颗粒都沿着发射器的顶部出现,使用它可以实现瀑布流等效果,示意图如下:
C: Rectangle shape
KCAEmitterLayerRectangle这种发射形态可以使得颗粒在一个指定的矩形区域随机的出现,使用它可以实现雪花飘落等效果,示意图如下:
而本节讲解的就是KCAEmitterLayerRectangle这种发射形态。
3) 确定发射器的位置及尺寸
emitter.emitterPosition = CGPointMake(rect.size.width * 0.5, rect.size.height * 0.5);
emitter.emitterSize = rect.size;
添加完上面的代码后,发射器的尺寸示意图如下:
4) 已经配置完发射器的位置及尺寸,就可以添加发射器单元了。
一个发射器单元就是一个数据模型,它用来呈现每一个颗粒,它是一个单独的类CAEmitterCell, 而 一个 CAEmitterLayer可以包含一个或者多个CAEmitterCell。现在我们就可以添加CAEmitterCell。接着添加如下代码:
CAEmitterCell *cell = [CAEmitterCell emitterCell];
cell.contents = [UIImage imageNamed:@"flake.png"];
这里,使用了一张叫做 "flake.png" 的图片作为cell的contents。而cell就会根据contents中的内容准备创建新的颗粒对象。"flake.png" 就是Demo效果预览中的白色小圆点。
5) 定制颗粒出现的个数及时间,代码如下:
cell.birthRate = 20;
cell.lifetime = 3.5;
emitter.emitterCells = @[cell];
birthRate: 一秒钟会产生颗粒的个数,lifetime: 颗粒持续时间;注意到,emitterCells是一个数组,说明一个发射器对象可以容纳多个CAEmitterCell对象;在下面的内容中会有说明。运行代码,效果如下图:
可以看出,这些颗粒在指定的3.5秒内出现或者消失。
6) 使这些颗粒动起来
cell.yAcceleration = 70.0;
cell.xAcceleration = 10.0;
cell.velocity = 20.0;
cell.emissionLongitude = -M_PI_2;
yAcceleration 和 xAcceleration 分别表示颗粒在y和x方向上面运动的加速度; velocity表示颗粒运动的速度;emissionLongitude表示颗粒初始时刻发射的方向(-M_PI_2 表示竖直往上发射)。 此时运行的效果如下图:
7) 产生随机速度
由于所有的颗粒都保持同样的速度20在运动,感受不到雪花纷飞的效果,所以我们应该使得产生的颗粒具有随机的速度。
cell.velocityRange = 200.0;
加上这句代码之后,随机产生的速度范围为 -180(20 - 200) 到 220(20 + 200) 。
同理,我们可以将发射器的发射角度随机化:
cell.emissionRange = M_PI_2;
当然,我也可以自定义颗粒的随机颜色:
cell.color = [UIColor colorWithRed:0.9 green:1.0 blue:1.0 alpha:1.0].CGColor;
cell.redRange = 0.3;
cell.greenRange = 0.3;
cell.blueRange = 0.3;
8) 随机颗粒的大小
cell.scale = 0.8;
cell.scaleRange = 0.8;
现实生活中,雪花的颗粒有大有小,所以添加上面两句代码,使得出现的颗粒比例大小范围是 0~1.6 倍默认颗粒的大小。
9) 仿真融化
cell.scaleSpeed = -0.15;
现实生活中,雪花在飘落的过程中, 伴随着风力温度等因素,会逐渐变小,所以添加了上面的代码;使得颗粒在运动过程中,以每秒减小15%的大小逐渐变小。
至此,单个cell的发射器效果就算好了,注意到上面的效果图中,发射器的起始y值位置为100,并且有背景色;他们只是用来进行测试的。我们可以去除掉背景色,并且将起始y设置为-70,将默认的发射颗粒改为150,运行之后的效果图如下:
当然,在本节中的开头,我所展示的是拥有多个cell的情况,就是emitterCells含有多个cell呈现的效果,大家可以自己试试。