首先放上效果图,大家可以看一下
实现的方法如下
一、使用到的类
- cakeyframeanimation // 核心动画-关键帧动画
- caemitterlayer // 粒子发射器(其实就是一个layer,其父类是calayer)
- caemittercell // 粒子
- ps:核心动画应该不用多说了;
- caemitterlayer和caemittercell,其实可以比喻成“炮”和“炮弹”,应该不难理解;
二、直接上部分关键代码 代码中会有详细的注释
2.1 .m中需要拥有的属性
1
2
|
/** weak类型 粒子发射器 */ @property (nonatomic, weak) caemitterlayer *emitterlayer; |
2.2 initwithframe: 方法中
1
2
3
4
5
6
7
8
|
- (instancetype)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { // 配置粒子发射器方法 [self setupemitter]; } return self; } |
2.3 setselected: 方法中
1
2
3
4
5
|
- ( void )setselected:( bool )selected { [super setselected:selected]; // 开始关键帧动画 [self keyframeanimation]; } |
2.4 layoutsubviews 方法中
1
2
3
4
5
|
- ( void )layoutsubviews{ [super layoutsubviews]; /// 设置粒子发射器的锚点 _emitterlayer.position = self.imageview.center; } |
2.5 setupemitter 方法中( 配置粒子发射器方法 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
- ( void )setup { // 粒子使用caemittercell初始化 caemittercell *emittercell = [caemittercell emittercell]; // 粒子的名字,在设置喷射个数的时候会用到 emittercell.name = @ "emittercell" ; // 粒子的生命周期和生命周期范围 emittercell.lifetime = 0.7; emittercell.lifetimerange = 0.3; // 粒子的发射速度和速度的范围 emittercell.velocity = 30.00; emittercell.velocityrange = 4.00; // 粒子的缩放比例和缩放比例的范围 emittercell.scale = 0.1; emittercell.scalerange = 0.02; // 粒子透明度改变范围 emittercell.alpharange = 0.10; // 粒子透明度在生命周期中改变的速度 emittercell.alphaspeed = -1.0; // 设置粒子的图片 emittercell.contents = (id)[uiimage imagenamed:@ "sparkle3" ].cgimage; /// 初始化粒子发射器 caemitterlayer *layer = [caemitterlayer layer]; // 粒子发射器的 名称 layer.name = @ "emitterlayer" ; // 粒子发射器的 形状(可以想象成打仗时,你需要的使用的炮的形状) layer.emittershape = kcaemitterlayercircle; // 粒子发射器 发射的模式 layer.emittermode = kcaemitterlayeroutline; // 粒子发射器 中的粒子 (炮要使用的炮弹) layer.emittercells = @[emittercell]; // 定义粒子细胞是如何被呈现到layer中的 layer.rendermode = kcaemitterlayeroldestfirst; // 不要修剪layer的边界 layer.maskstobounds = no; // z 轴的相对坐标 设置为-1 可以让粒子发射器layer在self.layer下面 layer.zposition = -1; // 添加layer [self.layer addsublayer:layer]; _emitterlayer = layer; } |
注意:这里有一点需要详细解释一下, caemittercell
的属性一般有两个参数:一个平均值和一个“range
”,比如:
1
2
3
|
// 粒子的生命周期和生命周期范围 emittercell.lifetime = 0.7; emittercell.lifetimerange = 0.3; |
这里苹果的官方文档是这样解释的:
每一个layer都有它自己的随机数发生器,粒子的属性大部分都被定义为一个平均值和一个范围值,
如粒子的速度,这个属性的值分布的区间为:[ m - r / 2,m + r / 2 ]。
然后 这个公式里面
m:均值(拿上面代码说就是 emittercell.lifetime
)
r:范围值(mittercell.lifetimerange
)
然后我们就可根据公式算出上面我设置的粒子的生命周期的范围是[0.7-0.3/2 , 0.7+0.3/2]
2.6 keyframeanimation 方法中 (开始关键帧动画)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- ( void )animation { // 创建关键帧动画 cakeyframeanimation *animation = [cakeyframeanimation animationwithkeypath:@ "transform.scale" ]; if (self.selected) { animation.values = @[@1.5 ,@0.8, @1.0,@1.2,@1.0]; animation.duration = 0.5; // 粒子发射器 发射 [self startfire]; } else { animation.values = @[@0.8, @1.0]; animation.duration = 0.4; } // 动画模式 animation.calculationmode = kcaanimationcubic; [self.imageview.layer addanimation:animation forkey:@ "transform.scale" ]; } |
这段代码没什么说的,应该很容易理解。
2.7 startfire 方法中 (开炮)
1
2
3
4
5
6
7
8
9
|
- ( void )startfire{ // 每秒喷射的80个 [self.emitterlayer setvalue:@1000 forkeypath:@ "emittercells.emittercell.birthrate" ]; // 开始 self.emitterlayer.begintime = cacurrentmediatime(); // 执行停止 [self performselector:@selector(stopfire) withobject:nil afterdelay:0.1]; } |
2.8 stopfire 方法中 (停火)
1
2
3
4
|
- ( void )stopfire { //每秒喷射的个数0个 就意味着关闭了 [self.emitterlayer setvalue:@0 forkeypath:@ "emittercells.emittercell.birthrate" ]; } |
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。