I have a space ship that I'm applying a force vector to using a joystick for control. I would like this to smoothly fly around when I'm switching directions.. Exactly like minisquadron if you've ever played that..

Let's say I move the joystick to the far right and apply a force on the physics body of (1,0) and then I abruptly switch directions without circling the joystick around and apply a force of (-1,0). The ship will move to the right and then slowly lose speed before switching in a linear fashion.

What I want is for it to slowly transition between those two vectors so that it flies in a tight circle.

I'm trying to figure out the best way to write this.. maybe using a loop.. but I could use some help.

pseudo code:

func joystickMoved(){
    let point = pointVector;

func moveShip(pointVector: pointVector){

    // get current angle  
    let curAngle = self.ship.physicsBody.velocity.toAngle()

    // get joystick angle
    let newAngle = pointVector.toAngle

    // while there is a sizeable difference in angles.. 
    // this loop needs to occur with some delay
    // so transition doesnt occur too quickly
    while fabsf(newAngle - curAngle) > 0.5 {

        // make tiny transitions towards newAngle.. this needs more detail
        curAngle += 1
        let newVelocity = CGPoint(cos(curAngle), sin(curAngle))
        self.ship.physicsBody.velocity = CGVector(dx: newVelocity.x, dy: newVelocity.y)


2 Answers 2

  • First, the behavior you're describing is that of an aerodynamic vehicle with a single vector of force. A spaceship, flying in space, would operate in an entirely different manner.

If this is still the desired behavior:

  • Second, to utilize SpriteKit's efficiency, it might be best to use actions on your nodes. This isn't a requirement, but they exist for a good reason.
  • Third, what you want is a single vector of force applied (say, from 0.0 to 1.0) in a single direction. The direction of the joystick should be the desired direction of the ship, the change of which is distributed over a time. If the joystick is analogue, the distance from center/rest would be the magnitude of the force applied.

This would look something like:

[spaceship runAction: [SKAction rotateToAngle:joystickAngle duration:joystickAngle/turnSpeed]];

Ensure, for the "tight circle" to be the effect, to keep the forward velocity/force applied throughout the duration.


My poor way of moving towards the touched location.

SKAction *rotation = [SKAction rotateToAngle:angle duration:.2 shortestUnitArc:YES];
SKAction *run = [SKAction moveTo:touchLocation duration:.01 * distance];

[ship removeAllActions];
[ship runAction:rotation completion:^{
    [self changeShipTextureWithType:@"run"];
    [ship runAction:run completion:^{
        [self changeShipTextureWithType:@"idle"];

PS: You wanna move while rotating, right? As in Space Rangers (video game)?


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .