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

Sam*_* V. 38 objective-c ios caemitterlayer

我正试图建立一个CAEmitterLayer制作五彩纸屑的效果,我遇到了两个问题:

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

这是我设置发射器的代码,然后启动和停止它(一旦我调用了stop函数,然后点击屏幕就会停止创建新的随机元素):

- (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];
}
Run Code Online (Sandbox Code Playgroud)

要开始五彩纸屑:

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

并阻止它:

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

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

任何帮助/见解将不胜感激!

谢谢,山姆

Gab*_*res 6

我知道这是一个老帖子,但我也有这个问题.Jackslash在这篇文章中回答得很好: iOS 7 CAEmitterLayer不恰当地产生粒子

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

emitter.beginTime = CACurrentMediaTime();
Run Code Online (Sandbox Code Playgroud)


Mar*_*kle 1

难道您没有像 Artur Ozieranski 发布的 Wenderlich 示例中那样检查粒子是否正在发射?只要支票到位,我就不会看到翻倍的情况。

- (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"];
}
Run Code Online (Sandbox Code Playgroud)