iOS CAEmitterLayer简介,基于CAEmitterLayer实现粒子效果 —— HERO博客

CAEmitterLayer简介:

CAEmitterLayer(粒子发射)继承自CALayer,提供了一个基于Core Animation的粒子发射系统,粒子用CAEmitterCell来初始化,一个单独的CAEmitterLayer可同时支持多个CAEmitterCell。


CAEmitterLayer属性:

  • emitterCells:CAEmitterCell对象的数组,用于把粒子投放到layer上。
  • birthRate:粒子产生速度,默认1个每秒。
  • lifetime:粒子纯在时间,默认1秒。
  • emitterPosition:发射器在xy平面的中心位置
  • emitterZPosition:发射器在z平面的位置
  • preservesDepth是否开启三维效果。
  • velocity粒子运动速度。
  • scale粒子的缩放比例。
  • spin自旋转速度。
  • seed用于初始化随机数产生的种子。
  • emitterSize发射器的尺寸
  • emitterDepth:发射器的深度
  • emitterShape:发射的形状
    • NSString * const kCAEmitterLayerPoint;//点的形状,粒子从一个点发出
    • NSString * const kCAEmitterLayerLine;//线的形状,粒子从一条线发出
    • NSString * const kCAEmitterLayerRectangle;//矩形形状,粒子从一个矩形中发出
    • NSString * const kCAEmitterLayerCuboid;//立方体形状,会影响Z平面的效果
    • NSString * const kCAEmitterLayerCircle;//圆形,粒子会在圆形范围发射
    • NSString * const kCAEmitterLayerSphere;//球型
  • emitterMode:发射器发射模式
    • NSString * const kCAEmitterLayerPoints;//从发射器中发出
    • NSString * const kCAEmitterLayerOutline;//从发射器边缘发出
    • NSString * const kCAEmitterLayerSurface;//从发射器表面发出
    • NSString * const kCAEmitterLayerVolume;//从发射器中点发出
  • renderMode:发射器渲染模式
    • NSString * const kCAEmitterLayerUnordered;//粒子无序出现
    • NSString * const kCAEmitterLayerOldestFirst;//声明久的粒子会被渲染在最上层
    • NSString * const kCAEmitterLayerOldestLast;//年轻的粒子会被渲染在最上层
    • NSString * const kCAEmitterLayerBackToFront;//粒子的渲染按照Z轴的前后顺序进行
    • NSString * const kCAEmitterLayerAdditive;//粒子混合


CAEmitterCell属性:

  • emitterCell:初始化方法。
  • name:粒子的名字。
  • color:粒子的颜色。
  • enabled:粒子是否渲染。
  • contents:渲染粒子,是个CGImageRef的对象,粒子要展示的图片。
  • contentsRect渲染范围。
  • birthRate:粒子产生速度。

  • lifetime:生命周期。
  • lifetimeRange:生命周期增减范围。
  • velocity:粒子运动速度。
  • velocityRange:速度范围。
  • spin:粒子旋转角度。
  • spinrange粒子旋转角度范围。
  • scale:缩放比例。
  • scaleRange:缩放比例范围。
  • scaleSpeed:缩放比例速度。
  • alphaRange::一个粒子的颜色alpha能改变的范围。
  • alphaSpeed::粒子透明度在生命周期内的改变速度。
  • redRange:一个粒子的颜色red能改变的范围。
  • redSpeed:粒子red在生命周期内的改变速度。
  • blueRange:一个粒子的颜色blue能改变的范围。
  • blueSpeed:粒子blue在生命周期内的改变速度。
  • greenRange:一个粒子的颜色green能改变的范围。
  • greenSpeed:粒子green在生命周期内的改变速度。
  • xAcceleration:粒子x方向的加速度分量。
  • yAcceleration:粒子y方向的加速度分量。
  • zAcceleration:粒子z方向的加速度分量。
  • emissionRange:粒子发射角度范围。
  • emissionLongitude:粒子在xy平面的发射角度。
  • emissionLatitude:发射的z轴方向的发射角度。

做了一个小Demo,效果图如下:


下面贴上代码:

#import "ViewController.h"

//获得屏幕的宽高
#define mainW [UIScreen mainScreen].bounds.size.width
#define mainH [UIScreen mainScreen].bounds.size.height

@interface ViewController ()

@property (nonatomic, strong) CAEmitterLayer *noteEmitter;
@property (nonatomic, strong) CAEmitterLayer *petalEmitter;
@property (nonatomic, strong) CAEmitterLayer *sunEmitter;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    
    //创建控件
    [self creatControl];
}

- (void)creatControl
{
    //唱歌小人背景
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((mainW - 170) * 0.5, mainH - 350, 170, 230)];
    imageView.image = [UIImage imageNamed:@"bj.jpg"];
    [self.view addSubview:imageView];
    
    //按钮标题数组
    NSArray *titleArray = @[@"唱歌", @"花瓣", @"太阳", @"停止"];
    //按钮宽度
    CGFloat btnWidth = 70;
    //按钮间距
    CGFloat padding = (mainW - btnWidth * titleArray.count) / (titleArray.count + 1);
    //创建按钮
    for (int i = 0; i < titleArray.count; i++) {
        UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(padding + (padding + btnWidth) * i, CGRectGetMaxY(imageView.frame) + 20, btnWidth, 30)];
        [btn setTitle:titleArray[i] forState:UIControlStateNormal];
        [btn setBackgroundColor:[UIColor orangeColor]];
        btn.tag = i;
        [btn addTarget:self action:@selector(btnOnClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btn];
    }
}

- (void)btnOnClick:(UIButton *)btn
{
    //唱歌按钮点击事件
    if (btn.tag == 0) {
        //重复点击先清空发射器
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        
        //初始化发射器
        _noteEmitter = [[CAEmitterLayer alloc] init];
        //粒子发射位置
        _noteEmitter.emitterPosition = CGPointMake(mainW * 0.5 + 15, 390);
        //发射源的尺寸大小
        _noteEmitter.emitterSize = CGSizeMake(10, 10);
        //发射模式
        _noteEmitter.renderMode = kCAEmitterLayerUnordered;
        //发射源的形状
        _noteEmitter.emitterMode = kCAEmitterLayerSurface;
        
        //发射单元
        NSMutableArray *cellArray = [NSMutableArray array];
        for (int i = 0; i < 3; i++) {
            CAEmitterCell *note = [CAEmitterCell emitterCell];
            //粒子产生速度
            note.birthRate = 0.7 + 0.5 * i;
            note.speed = 0.5;
            //粒子移动速度
            note.velocity = 100;
            //在原属性上增减的范围,现在粒子速度范围是100 - 30 ~ 100 + 30(70 ~ 130),其他属性后加Range同理
            note.velocityRange = 30;
            //粒子生命周期
            note.lifetime = 0.8;
            note.lifetimeRange = 0.1;
            //粒子旋转速度
            note.spin = 1;
            //粒子缩放比例
            note.scale = 0.1;
            note.scaleSpeed = 1;
            //粒子透明度变化速度
//            note.alphaSpeed = -0.8;
            //粒子发射角度
            note.emissionLongitude = M_PI + M_PI_2;
            note.emissionRange = M_PI_2;
            //随机生成图片名字
            NSString *str = [NSString stringWithFormat:@"note%d", arc4random_uniform(4)];
            note.contents = (__bridge id)[[UIImage imageNamed:str] CGImage];
            //粒子展示的图片
            NSString *name = [NSString stringWithFormat:@"note%d", i];
            //粒子的名字
            note.name = name;
            [cellArray addObject:note];
        }
        _noteEmitter.emitterCells = cellArray;
        //添加到layer层
        [self.view.layer addSublayer:_noteEmitter];
        
    //花瓣按钮点击事件
    }else if (btn.tag == 1) {
        [_petalEmitter removeFromSuperlayer];
        _petalEmitter = nil;
        
        _petalEmitter = [[CAEmitterLayer alloc] init];
        _petalEmitter.emitterPosition = CGPointMake(0, 0);
        _petalEmitter.emitterSize = CGSizeMake(mainW, 1);
        _petalEmitter.renderMode = kCAEmitterLayerOldestLast;
        _petalEmitter.emitterMode = kCAEmitterLayerPoints;
        _petalEmitter.emitterShape = kCAEmitterLayerRectangle;
        
        NSMutableArray *cellArray = [NSMutableArray array];
        for (int i = 0; i < 5; i++) {
            CAEmitterCell *petal = [CAEmitterCell emitterCell];
            petal.birthRate = 0.5 + 0.2 * i;
            petal.velocity = 100;
            petal.velocityRange = 100;
            petal.lifetime = 10;
            petal.spin = 0.5;
            petal.emissionLongitude = -M_PI - M_PI_2;
            petal.emissionRange = M_PI_2;
            NSString *str = [NSString stringWithFormat:@"petal%d", arc4random_uniform(5)];
            petal.contents = (__bridge id)[[UIImage imageNamed:str] CGImage];
            NSString *name = [NSString stringWithFormat:@"petal%d", i];
            petal.name = name;
            [cellArray addObject:petal];
        }
        _petalEmitter.emitterCells = cellArray;
        [self.view.layer addSublayer:_petalEmitter];
    
    //太阳按钮点击事件
    }else if (btn.tag == 2) {
        [_sunEmitter removeFromSuperlayer];
        _sunEmitter = nil;
        
        _sunEmitter = [CAEmitterLayer layer];
        _sunEmitter.frame = self.view.bounds;
        _sunEmitter.emitterPosition = CGPointMake(0, 0);
        _sunEmitter.renderMode = kCAEmitterLayerAdditive;
        
        CAEmitterCell *sun = [[CAEmitterCell alloc] init];
        sun.contents = (__bridge id)[UIImage imageNamed:@"petal4"].CGImage;
        sun.birthRate = 800;
        sun.lifetime = 2.0;
        sun.color = [UIColor colorWithRed:1 green:0.5 blue:0.1 alpha:1.0].CGColor;
        sun.alphaSpeed = -0.4;
        sun.velocity = 50;
        sun.velocityRange = 10;
        sun.emissionRange = M_PI * 2.0;
        _sunEmitter.emitterCells = @[sun];
        [self.view.layer addSublayer:_sunEmitter];
        
    //停止按钮点击事件
    }else if (btn.tag == 3) {
        [_noteEmitter removeFromSuperlayer];
        _noteEmitter = nil;
        [_petalEmitter removeFromSuperlayer];
        _petalEmitter = nil;
        [_sunEmitter removeFromSuperlayer];
        _sunEmitter = nil;
    }
}

@end




你可能感兴趣的:(iOS,Objective-C技术分享)