0
votes

I have a line of SKSPriteNodes, I want those nodes to move from top of the screen to the bottom, those nodes are not at the same CGPoint, they are behind each other forming a line, When I use the normal SKAction.MoveToY() and I give it duration they move at variant speed in order to all arrive at the same time, What I want is for all nodes to move at the same speed and arrive one after the other, keeping thier line form.

Here is how I create them:

     for i in 0...5 {
         let enemy = SKSPriteNode(imageNamed: "Enemy")
         enemy.position = CGPoint(x: size.width / 2, y: size.height + enemy.size.height * CGFloat(i))
         addChild(enemy)
         enemy.runAction(SKAction.moveToY(0 - size.height, duration: 5))
        }
2
Look at speed, time and a distance formulas (eg. time = distance/speed) You have to define the speed to calculate the time (duration parameter). Distance is already known. Or, as an alternative, if possible, put all nodes in one container node, and move just that one node. - Whirlwind
Would you please, elaborate more on the distance/speed calculation? distance is the entire height of the scene+enemy.position.y, speed is something I choose like 5 or 60? - Abdou023
Exactly. Checkout my answer. - Whirlwind

2 Answers

1
votes

Because action's duration parameter directly affects on how fast node is moving, you have to calculate that parameter properly, because in your case, every enemy node should travel different distance. As I said in the comments, formula to calculate time (duration parameter) is:

Time = Distance / Speed

You could do it like this:

class GameScene: SKScene{

struct Constants {
    static let enemySpeed:CGFloat = 100
}

override func didMoveToView(view: SKView) {


    print("Scene height : \(size.height)")

    print("Enemy speed : \(Constants.enemySpeed)")


    for i in 1...6 {

        //Creating random colors just for easier debugging.
        let randomColor = UIColor(red   : CGFloat(arc4random()) / CGFloat(UInt32.max),
            green : CGFloat(arc4random()) / CGFloat(UInt32.max),
            blue  : CGFloat(arc4random()) / CGFloat(UInt32.max),
            alpha : 1.0)

        let enemy = SKSpriteNode(color: randomColor, size:CGSize(width: 30, height: 30))
        enemy.zPosition = 10

        // Time = Distance / Speed

        let distance:CGFloat = frame.size.height + CGFloat(i) * enemy.size.height
        print("Enemy \(i) will travel \(distance) points")

        let duration = NSTimeInterval(distance / Constants.enemySpeed)
        print("Enemy \(i) will stop moving after \(duration) seconds")

        let enemyX = CGRectGetMidX(frame)
        let enemyY = frame.size.height + enemy.size.height/2 +  CGFloat(i) * enemy.size.height

        enemy.position = CGPoint(x: enemyX, y: enemyY)

        print("Enemy \(i) start position is \(enemy.position)")

        addChild(enemy)

        let endPosition = -enemy.size.height/2

        let move = SKAction.moveToY(endPosition, duration: duration)

         print("Enemy \(i) end position is \(-enemy.size.height/2)")

        enemy.runAction(move)
    }
}

}

As per 0x141E's suggestion, I've corrected distance calculation. Here is the output:

Scene height : 667.0
Enemy speed : 100.0
Enemy 1 will travel 697.0 points
Enemy 1 will stop moving after 6.97 seconds
Enemy 1 start position is (187.5, 712.0)
Enemy 1 end position is -15.0
Enemy 2 will travel 727.0 points
Enemy 2 will stop moving after 7.27 seconds
Enemy 2 start position is (187.5, 742.0)
Enemy 2 end position is -15.0
Enemy 3 will travel 757.0 points
Enemy 3 will stop moving after 7.57 seconds
Enemy 3 start position is (187.5, 772.0)
Enemy 3 end position is -15.0
Enemy 4 will travel 787.0 points
Enemy 4 will stop moving after 7.87 seconds
Enemy 4 start position is (187.5, 802.0)
Enemy 4 end position is -15.0
Enemy 5 will travel 817.0 points
Enemy 5 will stop moving after 8.17 seconds
Enemy 5 start position is (187.5, 832.0)
Enemy 5 end position is -15.0
Enemy 6 will travel 847.0 points
Enemy 6 will stop moving after 8.47 seconds
Enemy 6 start position is (187.5, 862.0)
Enemy 6 end position is -15.0
1
votes

Try using moveBy: instead of moveTo: - that way you can make all the sprites move by the same amount.