Abdou023
Abdou023

Reputation: 1664

Make nodes move to end point from different starting points at same speed

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

Upvotes: 0

Views: 456

Answers (2)

Jacek Lampart
Jacek Lampart

Reputation: 1751

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

Upvotes: 1

Whirlwind
Whirlwind

Reputation: 13665

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

Upvotes: 1

Related Questions