CAEmitterLayer会在触摸事件上发出随机不需要的粒子

时间:2012-07-11 20:30:20

标签: objective-c ios caemitterlayer

我正在尝试设置CAEmitterLayer来制作纸屑效果,我遇到了两个问题:

  1. 每当我将我的单元格上的birthRate设置为非零值以启动动画时,我会在屏幕上随机放置一系列单元格,这些单元格会正常生成动画,然后发射器继续正常发射。
  2. 每当emitterCells在屏幕上绘制内容时,无论何时触摸屏幕,发射器都会在(看似)随机位置绘制emitterCells(看似)随机时间。发射器中没有任何东西与任何触摸事件相关联(即,我不是故意在触摸事件上绘制任何东西),但是该层在具有多个嵌入视图的视图中。我触摸得越多,出现的细胞就越多。
  3. 这是我的代码,用于设置发射器,然后启动和停止它(一旦我调用了停止功能,然后点击屏幕停止创建新的随机元素):

    - (void)setupConfetti
    {
        self.confettiLayer = [CAEmitterLayer layer];
        [self.view.layer addSublayer:self.confettiLayer];
        [self.view.layer setNeedsDisplay];
    
        self.confettiLayer.emitterPosition = CGPointMake(1024.0/2,-50.0);
        self.confettiLayer.emitterSize = CGSizeMake(1000.0, 10.0);
        self.confettiLayer.emitterShape = kCAEmitterLayerLine; 
        self.confettiLayer.renderMode =kCAEmitterLayerUnordered;
    
        CAEmitterCell *confetti = [CAEmitterCell emitterCell];
    
        confetti1.contents =  (id)[[UIImage imageNamed:@"confetti.png"] CGImage];
    
        confetti.emissionLongitude = M_PI;
        confetti.emissionLatitude = 0;
        confetti.lifetime = 5;
        confetti.birthRate = 0.0;
        confetti.velocity = 125;
        confetti.velocityRange = 50;
        confetti.yAcceleration = 50;
        confetti.spin = 0.0;
        confetti.spinRange = 10;
        confetti.name = @"confetti1";
    
        self.confettiLayer.emitterCells = [NSArray arrayWithObjects:confetti, nil];
    }
    

    开始五彩纸屑:

    - (void)startConfettiAnimation
    {
        [self.confettiLayer setValue:[NSNumber numberWithInt:10.0] forKeyPath:@"emitterCells.confetti.birthRate"];
    }
    

    并阻止它:

    - (void)stopConfettiAnimation
    {
        [self.confettiLayer setValue:[NSNumber numberWithInt:0.0] forKeyPath:@"emitterCells.confetti.birthRate"];
    }
    

    同样,一旦它开始,在最初的随机元素之后,这很好用:一切都正常动画,当birthRate稍后设置为零时,它会优雅地结束。它似乎只是响应触摸事件,我不知道为什么。我已经尝试将emitterLayer添加到不同的视图,禁用该视图上的用户交互,然后将其添加为主视图的子视图,这似乎不起作用。

    非常感谢任何帮助/见解!

    谢谢, 萨姆

3 个答案:

答案 0 :(得分:6)

我知道这是一个老帖子,但我也有这个问题。 Jackslash在这篇文章中回答得很好: iOS 7 CAEmitterLayer spawning particles inappropriately

您需要在发射器层上设置beginTime以使用CACurrentMediaTime()在当前时间开始。似乎我们遇到的问题是因为发射器已经在过去开始了。

emitter.beginTime = CACurrentMediaTime();

答案 1 :(得分:1)

可能是因为你没有检查粒子是否像Wenderlich的例子中发出的那样Artur Ozieranski发布了吗?只要检查到位,我就不会看到加倍。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [fireView setEmitterPositionFromTouch: [touches anyObject]];
    [fireView setIsEmitting:YES];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [fireView setIsEmitting:NO];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [fireView setIsEmitting:NO];
}
-(void)setIsEmitting:(BOOL)isEmitting
{
    //turn on/off the emitting of particles
    [fireEmitter setValue:[NSNumber numberWithInt:isEmitting?200:0] forKeyPath:@"emitterCells.fire.birthRate"];
}

答案 2 :(得分:0)

  

.h文件

 #import <UIKit/UIKit.h>

    @interface DWFParticleView : UIView

    -(void)setEmitterPositionFromTouch: (CGPoint*)t;
    -(void)setIsEmitting:(BOOL)isEmitting;

    @end
  

.m文件

  #import "DWFParticleView.h"
    #import <QuartzCore/QuartzCore.h>

    @implementation DWFParticleView
    {
        CAEmitterLayer* fireEmitter; //1
    }

    -(void)awakeFromNib
    {
        //set ref to the layer
        fireEmitter = (CAEmitterLayer*)self.layer; //2
        //configure the emitter layer
        fireEmitter.emitterPosition = CGPointMake(50, 50);
        fireEmitter.emitterSize = CGSizeMake(10, 10);

        CAEmitterCell* fire = [CAEmitterCell emitterCell];
        fire.birthRate = 0;
        fire.lifetime = 1.5;
        fire.lifetimeRange = 0.3;
        fire.color = [[UIColor colorWithRed:255 green:255 blue:255 alpha:0.1] CGColor];
        fire.contents = (id)[[UIImage imageNamed:@"Particles_fire.png"] CGImage];
        [fire setName:@"fire"];

        fire.velocity =5;
        fire.velocityRange = 20;
        fire.emissionRange = M_PI_2;

        fire.scaleSpeed = 0.1;
        fire.spin = 0.5;

        fireEmitter.renderMode = kCAEmitterLayerAdditive;

        //add the cell to the layer and we're done
        fireEmitter.emitterCells = [NSArray arrayWithObject:fire];

    }

    + (Class) layerClass //3
    {
        //configure the UIView to have emitter layer
        return [CAEmitterLayer class];
    }

    -(void)setEmitterPositionFromTouch: (CGPoint*)t
    {
        //change the emitter's position
        fireEmitter.emitterPosition = (*t);
    }

    -(void)setIsEmitting:(BOOL)isEmitting
    {
        //turn on/off the emitting of particles
        [fireEmitter setValue:[NSNumber numberWithInt:isEmitting?100:0] forKeyPath:@"emitterCells.fire.birthRate"];
    }


    @end
  

我使用此代码创建自定义视图并发出粒子   触摸

     

以下是触摸粒子发射的调用声明

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint p =  [[touches anyObject] locationInView:self.view];
     [fireView setEmitterPositionFromTouch: &p];
     [fireView setIsEmitting:YES];

}
  

可能适合你。