Search code examples
sprite-kitjoystickgamecontroller

Dual Virtual Joystick for iOS simultaneous use


I'm using a virtual joystick for SpriteKit, and it works great. I have tried either JCInput version, or SpriteKit-Joystick version. Both were used for the movement, and used them on the left.

This is the code I used, although the documentation is very good in the gitHub anyway:

For JCInput version:

    self.joystick = [[JCJoystick alloc] initWithControlRadius:40 baseRadius:45 baseColor:[SKColor blueColor] joystickRadius:25 joystickColor:[SKColor redColor]];
    [self.joystick setPosition:CGPointMake(70,70)];
    [self addChild:self.joystick];

and the update function:

-(void)update:(CFTimeInterval)currentTime {

    [self.myLabel1 setPosition:CGPointMake(self.myLabel1.position.x+self.joystick.x, self.myLabel1.position.y+self.joystick.y)];

    [self.myLabel2 setPosition:CGPointMake(self.myLabel2.position.x+self.imageJoystick.x, self.myLabel2.position.y+self.imageJoystick.y)];

/* Called before each frame is rendered */

}

And for the SpriteKit-Joystick version:

    SKSpriteNode *jsThumb = [SKSpriteNode spriteNodeWithImageNamed:@"joystick"];
    [jsThumb setScale:0.5f];
    SKSpriteNode *jsBackdrop = [SKSpriteNode spriteNodeWithImageNamed:@"dpad"];
    [jsBackdrop setScale:0.5f];
    self.joystick = [Joystick joystickWithThumb:jsThumb andBackdrop:jsBackdrop];
    self.joystick.position = CGPointMake(50,50);
    [self addChild:self.joystick];
    //I've already declared it in the header file
    velocityTick = [CADisplayLink displayLinkWithTarget:self selector:@selector(joystickMovement)];
    [velocityTick addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

and the update function:

-(void)joystickMovement
{
    if (self.joystick.velocity.x != 0 || self.joystick.velocity.y != 0)
    {
        [self.myLabel1 setPosition:CGPointMake(self.myLabel1.position.x+.1 *self.joystick.velocity.x, self.myLabel1.position.y+.1 * self.joystick.velocity.y)];
    }
}

Now everything works perfectly, and don't have any issue with it. But I need to add another one to rotate my character (let's call it the self.myLabel1). I tried duplicating the object creation (with unique names, parameters and positions to put them to the right side of the screen, but other bits of code being exactly the same as what I used above).

They also work, but the problem is that they don't work simultaneously. I can either use the left one or the right one at any given time, and not together. Do I need to run them on two separate thread? I've tried using two CADisplayLinks with two separate Selectors, and nothing. I tried using the same one, and nothing.

Can anyone shed some light on this shadow?

Thanks a lot in advance.


Solution

  • You should be overriding update in your SKScene instead of using CADisplayLink. You can call joystickMovement from update and achieve the desired effect.

    You can read more about the different methods called as SKScene processes each frame in the SKScene class reference.

    If you haven't already, you'll also need to set multipleTouchEnabled to true in your SKScene's view. You can do this from your GameViewController with

    self.view.multipleTouchEnabled = YES;