Sprite kit 慢化SKEmitterNode的粒子

Sprite kit 慢化SKEmitterNode的粒子,sprite-kit,particles,skemitternode,Sprite Kit,Particles,Skemitternode,我只是好奇,有没有办法减缓粒子沿场景中其他对象的发射。假设您有一个粒子发射器和一个精灵。使用SKAction移动精灵。发射器正在发射。这两个节点都将添加到场景中。如果将self.speed设置为0.5,则只有精灵会减速。发射器将继续以相同的速度发射 除了使用particleSpeed属性外,还有其他方法可以减缓速度,因为这将改变发射器的行为 我的问题受到这个问题的启发:通常SKEmitterNode的速度有很多属性(xaccelevation,yaccelevation,particleSpee

我只是好奇,有没有办法减缓粒子沿场景中其他对象的发射。假设您有一个粒子发射器和一个精灵。使用
SKAction
移动精灵。发射器正在发射。这两个节点都将添加到场景中。如果将
self.speed
设置为0.5,则只有精灵会减速。发射器将继续以相同的速度发射

除了使用particleSpeed属性外,还有其他方法可以减缓速度,因为这将改变发射器的行为


我的问题受到这个问题的启发:

通常
SKEmitterNode
的速度有很多属性(
xaccelevation
yaccelevation
particleSpeedRange
particleScaleSpeed
):

因此,为了实现您的请求,我认为应该可以设置
targetNode

/**
     Normally the particles are rendered as if they were a child of the SKEmitterNode, they can also be rendered as if they were a child of any other node in the scene by setting the targetNode property. Defaults to nil (standard behavior).
     */
    weak open var targetNode: SKNode?
你可以向苹果官方了解更多细节

下面是一些代码示例:

class GameScene: SKScene {
    var myNode :SKSpriteNode!
    var myEmitter : SKEmitterNode!
    override func didMove(to view: SKView) {
        myNode = SKSpriteNode.init(color: .red, size: CGSize(width:100,height:100))
        self.addChild(myNode)
        myNode.position = CGPoint(x:self.frame.minX,y:self.frame.midY)
        let changePos = SKAction.run{
            [weak self] in
            guard let strongSelf = self else { return }
            if strongSelf.myNode.position.x > strongSelf.frame.maxX {
                strongSelf.myNode.position.x = strongSelf.frame.minX
            }
        }
        let move = SKAction.moveBy(x: 10.0, y: 0, duration: 0.5)
        let group = SKAction.group([move,changePos])
        myNode.run(SKAction.repeatForever(SKAction.afterDelay(1.0, performAction:group)))
        let showExplosion = SKAction.repeatForever(SKAction.afterDelay(3.0, performAction:SKAction.run {
            [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.myEmitter = strongSelf.newExplosion()
            strongSelf.addChild(strongSelf.myEmitter)
            strongSelf.myEmitter.targetNode = strongSelf.myNode
            strongSelf.myEmitter.particleSpeed = strongSelf.myNode.speed
            print("emitter speed is: \(strongSelf.myEmitter.particleSpeed)")
            strongSelf.myEmitter.position = CGPoint(x:strongSelf.frame.midX,y:strongSelf.frame.midY)
            strongSelf.myEmitter.run(SKAction.afterDelay(2.0, performAction:SKAction.removeFromParent()))
        }))
        self.run(showExplosion)
    }
    private func newExplosion() -> SKEmitterNode {
        let explosion = SKEmitterNode()
        let image = UIImage(named: "sparkle.png")!
        explosion.particleTexture = SKTexture(image: image)
        explosion.particleColor = UIColor.brown
        explosion.numParticlesToEmit = 100
        explosion.particleBirthRate = 450
        explosion.particleLifetime = 2
        explosion.emissionAngleRange = 360
        explosion.particleSpeed = 100
        explosion.particleSpeedRange = 50
        explosion.xAcceleration = 0
        explosion.yAcceleration = 0
        explosion.particleAlpha = 0.8
        explosion.particleAlphaRange = 0.2
        explosion.particleAlphaSpeed = -0.5
        explosion.particleScale = 0.75
        explosion.particleScaleRange = 0.4
        explosion.particleScaleSpeed = -0.5
        explosion.particleRotation = 0
        explosion.particleRotationRange = 0
        explosion.particleRotationSpeed = 0
        explosion.particleColorBlendFactor = 1
        explosion.particleColorBlendFactorRange = 0
        explosion.particleColorBlendFactorSpeed = 0
        explosion.particleBlendMode = SKBlendMode.add
        return explosion
    }
    func randomCGFloat(_ min: CGFloat,_ max: CGFloat) -> CGFloat {
        return (CGFloat(arc4random()) / CGFloat(UINT32_MAX)) * (max - min) + min
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        myNode.speed = randomCGFloat(0.0,50.0)
        print("new speed is: \(myNode.speed)")
    }
}
extension SKAction {
    class func afterDelay(_ delay: TimeInterval, performAction action: SKAction) -> SKAction {
        return SKAction.sequence([SKAction.wait(forDuration: delay), action])
    }
    class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction {
        return SKAction.afterDelay(delay, performAction: SKAction.run(block))
    }
}
class游戏场景:SKScene{
var myNode:SKSpriteNode!
var myEmitter:SKEmitterNode!
覆盖func didMove(到视图:SKView){
myNode=SKSpriteNode.init(颜色:。红色,大小:CGSize(宽度:100,高度:100))
self.addChild(myNode)
myNode.position=CGPoint(x:self.frame.minX,y:self.frame.midY)
让changePos=SKAction.run{
[虚弱的自我]在
guard let strongSelf=self-else{return}
如果strongSelf.myNode.position.x>strongSelf.frame.maxX{
strongSelf.myNode.position.x=strongSelf.frame.minX
}
}
让move=SKAction.moveBy(x:10.0,y:0,持续时间:0.5)
let group=SKAction.group([move,changePos])
myNode.run(SKAction.repeatForever(SKAction.afterDelay(1.0,性能:组)))
让showExplosion=SKAction.repeatForever(SKAction.afterDelay)(3.0,性能:SKAction.run{
[虚弱的自我]在
guard let strongSelf=self-else{return}
strongSelf.myEmitter=strongSelf.newExplosion()
strongSelf.addChild(strongSelf.myMitter)
strongSelf.myEmitter.targetNode=strongSelf.myNode
strongSelf.myMitter.particleSpeed=strongSelf.myNode.speed
打印(“发射器速度为:\(strongSelf.myEmitter.particleSpeed)”)
strongSelf.myEmitter.position=CGPoint(x:strongSelf.frame.midX,y:strongSelf.frame.midY)
strongSelf.myMitter.run(SKAction.afterDelay(2.0,性能:SKAction.removeFromParent()))
}))
自运行(showExplosion)
}
私有函数newExplosion()->SKEmitterNode{
let explosion=SKEmitterNode()
让image=UIImage(名为:“sparkle.png”)!
explosion.particleTexture=SKTexture(图像:图像)
explosion.particleColor=UIColor.brown
explosion.numParticlesToEmit=100
爆炸。颗粒物浓度=450
explosion.particleLifetime=2
explosion.emissionAngleRange=360
爆炸。颗粒速度=100
爆炸。微粒peedrange=50
explosion.x加速度=0
爆炸加速度=0
爆炸。微粒α=0.8
explosion.particleAlphaRange=0.2
explosion.particleAlphaSpeed=-0.5
爆炸。颗粒刻度=0.75
explosion.particleScaleRange=0.4
explosion.particleScaleSpeed=-0.5
explosion.particleRotation=0
explosion.particleRotationRange=0
explosion.particle旋转速度=0
explosion.particleColorBlendFactor=1
explosion.particleColorBlendFactorRange=0
explosion.particleColorBlendFactors速度=0
explosion.particleBlendMode=SKBlendMode.add
回程爆炸
}
func randomCGFloat(umin:CGFloat,max:CGFloat)->CGFloat{
返回值(CGFloat(arc4random())/CGFloat(UINT32_MAX))*(MAX-min)+min
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
myNode.speed=randomCGFloat(0.0,50.0)
打印(“新速度为:\(myNode.speed)”)
}
}
扩展动作{
类func afterDelay(delay:TimeInterval,performation action:SKAction)->SKAction{
返回SKAction.sequence([SKAction.wait(forDuration:delay),action])
}
类func afterDelay(delay:TimeInterval,runBlock:@escaping()->Void)->SKAction{
返回SKAction.afterDelay(延迟,性能:SKAction.run(块))
}
}

在本例中,您可以看到每次我触摸屏幕时应用于
myNode
的速度是如何涉及
mymitter
的速度的,因为发射器的
targetNode
属性设置为
myNode
,我还将
粒子速度
改为更真实的减速/加速。

你想减慢粒子的运动和粒子的发射速率吗?@我觉得很困惑(但这只是猜测,因为我还没有真正测试过)就像你们建议的那个样,每次需要为不同的发射器设置不同的值/数学,因为粒子的运动涉及到很多因素。也许你可以写一个答案来确切地说明你想要使用什么值/数学?你是否建议更改targetNode的速度会减慢粒子系统?targetNode应该会影响涉及兴趣的粒子。我没试过,也没怎么用SK粒子。SCN粒子系统的速度特性会影响现有粒子的速度及其发射率。这听起来像是达到了同样的目的。如果有用的话,@AlessandroOrnano会在我有时间的时候试试这个,谢谢。希望这能起作用,至少对于设置了targetNode的节点来说,这是一个解决方案。下面是SCNParticleSystem属性屏幕截图底部的速度值:如果你玩这个,它会减慢系统的速度
class GameScene: SKScene {
    var myNode :SKSpriteNode!
    var myEmitter : SKEmitterNode!
    override func didMove(to view: SKView) {
        myNode = SKSpriteNode.init(color: .red, size: CGSize(width:100,height:100))
        self.addChild(myNode)
        myNode.position = CGPoint(x:self.frame.minX,y:self.frame.midY)
        let changePos = SKAction.run{
            [weak self] in
            guard let strongSelf = self else { return }
            if strongSelf.myNode.position.x > strongSelf.frame.maxX {
                strongSelf.myNode.position.x = strongSelf.frame.minX
            }
        }
        let move = SKAction.moveBy(x: 10.0, y: 0, duration: 0.5)
        let group = SKAction.group([move,changePos])
        myNode.run(SKAction.repeatForever(SKAction.afterDelay(1.0, performAction:group)))
        let showExplosion = SKAction.repeatForever(SKAction.afterDelay(3.0, performAction:SKAction.run {
            [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.myEmitter = strongSelf.newExplosion()
            strongSelf.addChild(strongSelf.myEmitter)
            strongSelf.myEmitter.targetNode = strongSelf.myNode
            strongSelf.myEmitter.particleSpeed = strongSelf.myNode.speed
            print("emitter speed is: \(strongSelf.myEmitter.particleSpeed)")
            strongSelf.myEmitter.position = CGPoint(x:strongSelf.frame.midX,y:strongSelf.frame.midY)
            strongSelf.myEmitter.run(SKAction.afterDelay(2.0, performAction:SKAction.removeFromParent()))
        }))
        self.run(showExplosion)
    }
    private func newExplosion() -> SKEmitterNode {
        let explosion = SKEmitterNode()
        let image = UIImage(named: "sparkle.png")!
        explosion.particleTexture = SKTexture(image: image)
        explosion.particleColor = UIColor.brown
        explosion.numParticlesToEmit = 100
        explosion.particleBirthRate = 450
        explosion.particleLifetime = 2
        explosion.emissionAngleRange = 360
        explosion.particleSpeed = 100
        explosion.particleSpeedRange = 50
        explosion.xAcceleration = 0
        explosion.yAcceleration = 0
        explosion.particleAlpha = 0.8
        explosion.particleAlphaRange = 0.2
        explosion.particleAlphaSpeed = -0.5
        explosion.particleScale = 0.75
        explosion.particleScaleRange = 0.4
        explosion.particleScaleSpeed = -0.5
        explosion.particleRotation = 0
        explosion.particleRotationRange = 0
        explosion.particleRotationSpeed = 0
        explosion.particleColorBlendFactor = 1
        explosion.particleColorBlendFactorRange = 0
        explosion.particleColorBlendFactorSpeed = 0
        explosion.particleBlendMode = SKBlendMode.add
        return explosion
    }
    func randomCGFloat(_ min: CGFloat,_ max: CGFloat) -> CGFloat {
        return (CGFloat(arc4random()) / CGFloat(UINT32_MAX)) * (max - min) + min
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        myNode.speed = randomCGFloat(0.0,50.0)
        print("new speed is: \(myNode.speed)")
    }
}
extension SKAction {
    class func afterDelay(_ delay: TimeInterval, performAction action: SKAction) -> SKAction {
        return SKAction.sequence([SKAction.wait(forDuration: delay), action])
    }
    class func afterDelay(_ delay: TimeInterval, runBlock block: @escaping () -> Void) -> SKAction {
        return SKAction.afterDelay(delay, performAction: SKAction.run(block))
    }
}