【问题标题】:CAEmitterLayer emits random unwanted particles on touch eventsCAEmitterLayer 在触摸事件中随机发射不需要的粒子
【发布时间】:2023-04-04 12:55:02
【问题描述】:

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

  1. 每当我将单元格上的 birthRate 设置为非零值以启动动画时,我都会在屏幕上随机放置一系列单元格,这些单元格可以正常动画,然后发射器在此之后继续正常发射。李>
  2. 每当emitterCells 在屏幕上绘制东西时,只要我触摸屏幕,发射器就会在(看似)随机位置绘制emitterCells,这些位置存在(看似)随机的时间量。发射器中的任何内容都与任何触摸事件无关(即我不是故意在触摸事件上绘制任何东西),但该层位于具有多个嵌入式视图的视图中。我触摸的次数越多,显示的单元格就越多。

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

- (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 添加到不同的视图,禁用该视图上的用户交互,然后将其添加为主视图的子视图,但这似乎不起作用。

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

谢谢, 山姆

【问题讨论】:

  • 您对此有什么了解吗?我也有同样的问题。对我来说似乎是一个非常不必要的“功能”。
  • 也许自上次在这篇文章中发表评论一年后,有人确实找到了这个问题的解决方案?我在使用 CAEmitterLayer 类的网络上创建的每个项目中都看到了这个问题。您甚至可以尝试使用本教程:raywenderlich.com/6063/uikit-particle-systems-in-ios-5-tutorial。例如,只需从 vc 中删除触摸处理并将birthRate 降低到 1,然后开始在任何地方录制。点击后所有的活粒子似乎都加倍了。该问题仅出现在设备上,而不出现在模拟器中。

标签: objective-c ios caemitterlayer


【解决方案1】:

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

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

emitter.beginTime = CACurrentMediaTime();

【讨论】:

    【解决方案2】:

    您是否没有像 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"];
    }
    

    【讨论】:

      【解决方案3】:

      .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];
      
      }
      

      也许它对你有用。

      【讨论】:

        猜你喜欢
        • 2015-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-06
        • 1970-01-01
        • 2018-08-23
        • 1970-01-01
        相关资源
        最近更新 更多