2017-01-23 10 views
2

Мне было просто любопытно, есть ли способ замедлить частицу, излучающую другие объекты в сцене. Скажем, у вас есть один излучатель частиц и один спрайт. Sprite перемещается с использованием SKAction. Испускает излучатель. Оба узла добавляются в сцену. Если вы установите self.speed на 0,5, только спрайт замедлит работу. Излучатели будут продолжать излучать с той же скоростью.Замедление частиц SKEmitterNode

Есть ли способ замедления каким-то другим способом, чем использование свойства particleSpeed, поскольку это изменит поведение излучателя.

Мой вопрос навеян этот вопрос: https://stackoverflow.com/a/41764180/3402095

+0

Вы хотите замедлить движение частиц ** И ** скорость, с которой испускаются частицы? – Confused

+0

@Confused Я думаю (но это просто угадание, потому что я действительно не тестировал), что что-то вроде вас предложило бы каждый раз использовать разные значения/математику для разных эмиттеров, потому что в движении частицы участвуют многие факторы. Может быть, вы можете написать ответ, чтобы точно показать, какие ценности/математику вы хотели использовать? – Whirlwind

ответ

1

Обычно SKEmitterNode имеют много свойств, связанных с его скорость (xAcceleration, yAcceleration, particleSpeedRange, particleScaleSpeed ..):

private func newExplosion() -> SKEmitterNode { 
     let explosion = SKEmitterNode() 
     let image = UIImage(named:"spark.png")! 
     explosion.particleTexture = SKTexture(image: image) 
     explosion.particleColor = SKColor.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 
    } 

Итак, чтобы достичь вашего запрос Я думаю, что должно быть возможно установить 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? 

Более подробную информацию вы можете получить у официального представителя Apple docs.

Некоторые код, например:

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)) 
    } 
} 

В этом примере вы можете увидеть, как скорость применительно к myNode участвует скорость myEmitter каждый раз я коснуться экрана, потому что эмиттер имеют targetNode свойство выставиться с myNode, и я также изменил particleSpeed, что кажется более реалистичным замедление/акселерация.

+1

Это ваше предложение, что изменение скорости targetNode замедлит систему частиц? – Confused

+0

TargetNode должен влиять на вовлеченные частицы –

+0

Интересно. Я не пробовал этого и не использовал SK-частиц. Системы частиц SCN имеют свойство скорости, которое влияет на скорость существующих частиц и их скорость эмиттанса. Похоже, он достигнет того же. Если он работает. – Confused