objective-cvectorsprite-kittop-down

Spritekit top down turning character movement


I'm creating a top down 'racer' game if you will in Spritekit. However, I'm already stuck in creating the gameplay. You control a car from a top down view which is always driving at a constant speed. The player can press two buttons to turn the car left or right. The speed has to remain constant, but the zRotation of the car has to change. Changing the zRotation isn't the problem, but defining the new velocity of the car is.

I'm currently working with Vectors, so say every time the player presses the 'turnLeft' button the zRotation of the car changes with 45 degrees and a constant velocity of 20, the new velocity would be:

    player.physicsBody.velocity = CGVectorMake(14.14, 14.14);

Given by using the sin and cos of 45 degrees and sum of vectors giving the constant speed 20 ( triangle with two 45 degrees angles and one side of 20).

However, I have no idea how I should make this variable every time the player holds the turnLeft button, and if I should use actions or the update function. It should be possible for the player to drive a circle if he chooses to hold the turnLeft button forever. Any help is appreciated! Thanks.


Solution

  • To calculate the components of the velocity you basically need to do what you stated, except use the zRotation of your sprite in place of 45 degrees. For example:

    let speed: CGFloat = 20 // The constant speed.
    
    // Work out the components of velocity:
    let dx = speed * cos(sprite.zRotation)
    let dy = speed * sin(sprite.zRotation)
    
    sprite.physicsBody!.velocity = CGVector(dx: dx, dy: dy)
    

    As an improvement, it would be better to add this code as an initialiser of CGVector, for reusability:

    extension CGVector {
        init(length: CGFloat, angle: CGFloat) {
            self.dx = length * cos(angle)
            self.dy = length * sin(angle)
        }
    }
    

    You can then use this like so:

    sprite.physicsBody!.velocity = CGVector(length: speed, angle: sprite.zRotation)
    

    Hope that answers your question.