1

我正在使用 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。

4

2 回答 2

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]]];
于 2015-05-28T18:24:18.947 回答
1

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

请参阅SKEmitterNode 文档页面上的“使用关键帧序列配置粒子属性的自定义斜坡”的讨论。

于 2015-05-28T18:31:29.290 回答