【问题标题】:How can I EaseIn/Out SKEmitterNode.particleBirthRate我怎样才能缓入/缓出 SKEmitterNode.particleBirthRate
【发布时间】:2015-05-28 15:22:51
【问题描述】:

我正在使用 SKEmitterNode 来发射一些点击时的粒子。我追求类似于潜望镜中的心脏的效果。

我发现当我添加发射器时,它的行为不像刚刚“打开”。也就是说,粒子在远离生成点的地方以完整的 alpha 出现(好像它们已经存活了一段时间)。就好像发射器一直在运行它突然显示出来一样。

我所追求的是点击->添加节点->从点开始发射->发射一段时间->关闭->删除节点。

我尝试使用 GCD 调整particleBirthRate:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    if(self.burstEmitter.parent){
        return;
    }

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInNode:self];
    self.burstEmitter.position = point;
    self.burstEmitter.particleBirthRate = 0;
    [self addChild:self.burstEmitter];


    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.burstEmitter.particleBirthRate = 10;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.burstEmitter.particleBirthRate = 0;

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self removeAllChildren];
            });
        });
    });
}

然后我认为 SKAction 可能是正确的工具(它可能是......)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    if(self.burstEmitter.parent){
        return;
    }

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInNode:self];
    self.burstEmitter.position = point;
    self.burstEmitter.particleBirthRate = 10;
    [self addChild:self.burstEmitter];


    [self.burstEmitter runAction:[SKAction sequence:@[
                                                      [SKAction fadeInWithDuration:1],
                                                      [SKAction waitForDuration:2],
                                                      [SKAction fadeOutWithDuration:1],
                                                      [SKAction removeFromParent]
                                                      ]]];
}

这显然使发射器节点淡出,而不是“关闭”,

我愿意使用 CAEmitterLayer。我也尝试过,但遇到了同样的问题。


更新:我找到了一种解决方案:resetSimulation。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    if(self.burstEmitter.parent){
        return;
    }

    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInNode:self];
    self.burstEmitter.position = point;
    self.burstEmitter.particleBirthRate = 10;
    [self.burstEmitter resetSimulation];
    [self addChild:self.burstEmitter];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.burstEmitter.particleBirthRate = 0;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self removeAllChildren];
        });
    });
}

这完成了我所追求的。如果可能的话,我仍然很好奇为此使用 SKAction。

【问题讨论】:

    标签: ios sprite-kit skemitternode


    【解决方案1】:

    您可以使用 SKAction 块。有多种方法可以完成您的要求。这是一个简单的:

    SKAction *wait0 = [SKAction waitForDuration:0.5]; // time in secs
    SKAction *block0 = [SKAction runBlock:^{
        self.burstEmitter.particleBirthRate = 9;
    }];
    SKAction *block1 = [SKAction runBlock:^{
        self.burstEmitter.particleBirthRate = 8;
    }];
    SKAction *block2 = [SKAction runBlock:^{
        self.burstEmitter.particleBirthRate = 7;
    }];
    
    // and so on...
    
    [self runAction:[SKAction sequence:@[block0, wait0, block1, wait0, block2]]];
    

    【讨论】:

      【解决方案2】:

      使用 SKKeyframeSequence。这就是它的用途。

      请参阅SKEmitterNode docs page 上关于“使用关键帧序列为粒子属性配置自定义渐变”的讨论。

      【讨论】:

      • 如果particleBirthRate 属性本身是可动画的就好了,就像CAEmitterCell 和CAEmitterLayer 属性一样;但我没有看到任何证据。
      猜你喜欢
      • 1970-01-01
      • 2023-01-08
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2018-07-15
      • 2015-03-12
      • 2020-04-05
      • 1970-01-01
      相关资源
      最近更新 更多