不启用动画更改,指定随机粒子开始颜色?

7
有没有一种方法可以使粒子以基于当前“颜色坡道”的随机颜色生成?这些粒子在它们的寿命期间不会改变颜色,它们仅在出生时从“颜色坡道”中的某个位置分配颜色,并保持该颜色直到它们死亡。
这将导致在出生时混合从红色到蓝色的颜色的粒子。
在我的测试中,我似乎只能获得粒子生成为红色,然后随着它们接近屏幕底部逐渐变为蓝色的行为。

你不希望它们动画到屏幕底部,而是保持原地并改变颜色吗? - John Riselvato
1
@JohnRiselvato - 通过使用颜色渐变,粒子从红色(顶部)到蓝色(底部)进行动画。我想要的不是让粒子以任何颜色进行动画,而是生成具有恒定颜色(来自渐变)的粒子,然后在它们的整个寿命中保持该颜色。就像树上落下的秋叶,有些是绿色的,有些是黄色的,有些是橙色的,它们只是以各自的颜色开始并落下(它们不会在落下时改变颜色)。 - fuzzygoat
我使用了雪作为原始素材,然后将精灵更改为叶子(病态的,添加*.png文件)。 - fuzzygoat
1
我认为问题在于颜色渐变只能随时间变化,所有粒子始终是红色的(然后您可以选择从红色到蓝色混合)。我认为这不允许您基于渐变为每个粒子分配固定的混合颜色。 - fuzzygoat
2个回答

8
好的,看起来你不能使用预定义的sks文件来创建SKEmitterNode...我通过以编程方式创建SKEmitterNode来解决了这个问题。原因是当你使用sks初始化一个SKEmitterNode时,它似乎不会响应setParticleColor:,但以编程方式初始化就可以。
现在,今天,在过去的一个小时里,是我第一次尝试使用SKEmitterNode,所以你需要忍耐我,因为我无法完美地实现雪花效果,但我相信你可以通过更改SKEmitterNode允许更改的值来实现。
无论如何,我假设SKEmitterNode在SKScene上呈现(这是我知道如何获得你想要的效果的唯一方法)。
首先,你需要将SKEmitterNode作为全局/属性等进行声明,因为稍后你需要访问它。
MyScene.m中:
@implementation MyScene {
    SKEmitterNode* leafEmitter;
}

-(id)initWithSize:(CGSize)size {    
        leafEmitter = [[SKEmitterNode alloc] init];
        [leafEmitter setParticleTexture:[SKTexture textureWithImageNamed:@"saFMB.png"]];
        [leafEmitter setParticleBirthRate:10];
        [leafEmitter setScale:0.5];
        [leafEmitter setYAcceleration:-10.0];
        [leafEmitter setParticleSpeedRange:100];
        [leafEmitter setParticleLifetimeRange:100.0];
        [leafEmitter setParticlePositionRange:CGVectorMake(self.size.width, self.size.height)];
        [leafEmitter setPosition:CGPointMake(100, 400)];
        [leafEmitter setParticleBlendMode:SKBlendModeAlpha];
        [self addChild:leafEmitter];
}

所以我在这里编写了程序来创建粒子效果,这是您将更改动画/速度/等变量以获得最佳粒子效果的地方。我建议阅读此文以获取更多详细信息。
现在还记得我说过它需要在SKScene上呈现吗?那是因为我们将利用随着SKScene一起提供的update:(CFTimeInterval)currentTime函数。
update:(CFTimeInterval)currentTime内部,我们将更改SKEmitterNode的颜色。由于此更新功能每帧调用一次,因此可以轻松更改颜色,无需任何花哨的计时器或类似物。不确定这是否是个好主意,但重要的是想法。
-(void)update:(CFTimeInterval)currentTime {
[leafEmitter setParticleColor:[UIColor colorWithHue:drand48() saturation:1.0 brightness:1.0 alpha:1.0]];
[leafEmitter setParticleColorBlendFactor:1.0];
    /* Called before each frame is rendered */
}

在这种情况下,我们将颜色更改为随机RGB值,但我会让你自己选择颜色。
作为回报,这是我的代码所产生的:

enter image description here


所有这些说法,很遗憾,仅使用粒子接口似乎无法获得您想要的效果。

1
嗨John,感谢你花费时间和精力来整理答案。我明白你的意思,看起来很不错,我明天会试一试。非常感谢,完美的答案。 - fuzzygoat
1
如果将SKEmitterNode的'particleColorSequence'变量设置为nil,则SKParticleColor不再被忽略。创建SKS通常会将其设置为非nil,导致其他颜色属性被忽略。 - OwlOCR

2
我发现的有效方法,无需向update()函数添加代码,就是对emitter应用以下更改。
@john-riselvato是正确的(即使在7年后),使用编辑器来定义它,但你可以用以下代码获得所需的效果。
import Foundation
import SpriteKit

class RandomColorEmitterNode : SKEmitterNode {

    override init() {
        super.init()
    
        self.particleColorSequence = nil
        self.particleColorBlendFactorSequence = nil
        self.particleColorBlueRange = 255
        self.particleColorGreenRange = 255
        self.particleColorRedRange = 255
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    
        self.particleColorSequence = nil
        self.particleColorBlendFactorSequence = nil
        self.particleColorBlueRange = 255
        self.particleColorGreenRange = 255
        self.particleColorRedRange = 255
    }
}

通过简单的调用:

if let emitter = RandomColorEmitterNode(fileNamed: "flower.sks") {
    self.addChild(emitter)
}

发射器最初从您在编辑器中创建的SKS文件加载,然后颜色属性被类覆盖。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接