使用带粒子效果的 CAEmitterLayer

下雪 下雨 等粒子动画效果

CAEmitterLayer用GPU渲染 不占用CPU

 

极客学院视频地址 http://www.jikexueyuan.com/course/1302_1.html?ss=2

 

ViewController.h

#import "ViewController.h"
#import "CAEmitterLayerView.h"
#import "SnowView.h"
#import "RainView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    
    //MARK: 1.用 CAEmitterLayer 产生粒子效果
    [self mark1];
    
    //MARK: 2.封装 CAEmitterLayer
    
    CAEmitterLayerView *layerView = [[CAEmitterLayerView alloc]initWithFrame:CGRectZero];
    NSLog(@"%@",layerView.layer);
    
    //MARK: 3.封装下雪、下雨的粒子效果控件
    // 优化效果 添加alpha图层 模糊边界效果
    UIImageView *alphaView1       = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    alphaView1.image              = [UIImage imageNamed:@"alpha"];
    UIImageView *alphaView2       = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    alphaView2.image              = [UIImage imageNamed:@"alpha"];
    
    // 添加下雪效果  (在这里复习一下多态 用父类指针指向子类创建出来的对象)
    CAEmitterLayerView *snowView  = [[SnowView alloc]initWithFrame:CGRectMake(100, 220, 100, 100)];
    snowView.maskView             = alphaView1;
    [self.view addSubview:snowView];
    [snowView show];
    
    // 添加下雨效果
    CAEmitterLayerView *rainView  = [[RainView alloc]initWithFrame:CGRectMake(220, 220, 100, 100)];
    rainView.maskView             = alphaView2;
    [self.view addSubview:rainView];
    [rainView show];
}

- (void)mark1 {
    //第一步 创建出Layer
    CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
    
    // 设置基本信息
    emitterLayer.borderWidth     = 1.f;
    
    // 给定尺寸
    emitterLayer.frame           = CGRectMake(100, 100, 100, 100);
    // 不让粒子超出layer的范围
    emitterLayer.masksToBounds   = YES;
    // 粒子发射点坐标
    emitterLayer.emitterPosition = CGPointMake(0, 0);
    // 发射模式
    emitterLayer.emitterMode     = kCAEmitterLayerSurface;
    // 发射形状
    emitterLayer.emitterShape    = kCAEmitterLayerLine;
    
    // 添加layer
    [self.view.layer addSublayer:emitterLayer];
    
    //第二步 创建粒子
    CAEmitterCell * cell         = [CAEmitterCell emitterCell];
    
    // 粒子产生率
    cell.birthRate               = 1.f;
    // 粒子生命周期 设置成120秒
    cell.lifetime                = 120.f;
    // 粒子运动的速度值(10) 以及加减的范围(7~13)
    cell.velocity                = 10.f;
    cell.velocityRange           = 3.f;
    // y轴加速度
    cell.yAcceleration           = 2.f;
    // 粒子发射范围的角度
    cell.emissionRange           = 4 * M_1_PI;
    // 设置粒子颜色
    cell.color                   = [UIColor blackColor].CGColor;
    // 设置粒子图片
    cell.contents                = (__bridge id)[UIImage imageNamed:@"snow"].CGImage;
    
    
    //第三步 让CAEmitterLayer和CAEmitterCell产生关联
    emitterLayer.emitterCells    = @[cell];
}

 
模拟一个抽象的父类CAEmitterLayerView

CAEmitterLayerView.h

@interface CAEmitterLayerView : UIView


//模拟一个抽象的父类

/*
 模仿setter,getter方法 用.语法解决设置有很多参数的问题
 */
- (void)setEmitterLayer:(CAEmitterLayer *)layer;
- (CAEmitterLayer *)emitterLayer;

//显示出当前View
- (void)show;
//隐藏当前View
- (void)hide;

 CAEmitterLayerView.m

@interface CAEmitterLayerView () {
    
    CAEmitterLayer * _emitterLayer;
    
}

@end


@implementation CAEmitterLayerView

//创建layer的过程中把CALayer替换成CAEmitterLayer
+ (Class)layerClass {
    return [CAEmitterLayer class];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        _emitterLayer = (CAEmitterLayer *)self.layer;
        
    }
    return self;
}

- (void)setEmitterLayer:(CAEmitterLayer *)layer {
    _emitterLayer = layer;
}

- (CAEmitterLayer *)emitterLayer {
    return _emitterLayer;
}

- (void)show {
    //这里可以说是 里氏代换原则 每个继承了CAEmitterLayerView的子类都有show的方法 但是都可以重写 实现不同的功能(只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为)
}

- (void)hide {
    
}

 

继承了CAEmitterLayerView的SnowView和RainView

SnowView.m

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        [self initEmitterLayerProperties];
        
    }
    return self;
}

- (void)initEmitterLayerProperties {
    //初始化一些参数
    self.emitterLayer.masksToBounds   = YES;
    self.emitterLayer.emitterShape    = kCAEmitterLayerLine;
    self.emitterLayer.emitterMode     = kCAEmitterLayerSurface;
    self.emitterLayer.emitterSize     = self.frame.size;
    self.emitterLayer.emitterPosition = CGPointMake(self.bounds.size.width / 2.f, - 20);
}


- (void)show {
    //添加 CAEmitterCell
    CAEmitterCell *snowflake  = [CAEmitterCell emitterCell];
    snowflake.birthRate       = 1.f;
    snowflake.speed           = 10.f;
    snowflake.velocity        = 2.f;
    snowflake.velocityRange   = 10.f;
    snowflake.yAcceleration   = 10.f;
    snowflake.emissionRange   = 0.5 * M_PI;
    snowflake.spinRange       = 0.25 * M_PI;
    snowflake.contents        = (__bridge id)([UIImage imageNamed:@"snow"].CGImage);
    snowflake.color           = [UIColor redColor].CGColor;
    snowflake.lifetime        = 60.f;
    snowflake.scale           = 0.5;
    snowflake.scaleRange      = 0.3;
    
    // 添加动画
    self.emitterLayer.emitterCells = @[snowflake];
}

 RainView.m

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 初始化设置
        [self setup];
    }
    return self;
}

- (void)setup {
    self.emitterLayer.masksToBounds   = YES;
    self.emitterLayer.emitterShape    = kCAEmitterLayerLine;
    self.emitterLayer.emitterMode     = kCAEmitterLayerSurface;
    self.emitterLayer.emitterSize     = self.frame.size;
    self.emitterLayer.emitterPosition = CGPointMake(self.bounds.size.width / 2.f, - 20);
}

- (void)show {
    // 配置
    CAEmitterCell *rainflake  = [CAEmitterCell emitterCell];
    rainflake.birthRate       = 25.f;
    rainflake.speed           = 10.f;
    rainflake.velocity        = 10.f;
    rainflake.velocityRange   = 10.f;
    rainflake.yAcceleration   = 1000.f;
    rainflake.contents        = (__bridge id)([UIImage imageNamed:@"rain"].CGImage);
    rainflake.color           = [UIColor blackColor].CGColor;
    rainflake.lifetime        = 7.f;
    rainflake.scale           = 0.2f;
    rainflake.scaleRange      = 0.f;
    
    // 添加动画
    self.emitterLayer.emitterCells = @[rainflake];
}
 
posted @ 2015-08-06 17:14  lxl奋小斗  阅读(217)  评论(0编辑  收藏  举报