Search code examples
iosswiftsprite-kitjoystick

SpriteKit: calculate angle of joystick and change sprite based on that


I am making a RPG Birds-eye style game with SpriteKit. I made a joystick because a D-Pad does not give the player enough control over his character.

I cannot wrap my brain around how I would calculate the neccessary data needed to change the Sprite of my character based on the angle of the joystick thumb Node.

Here is my code I am using

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        if isTracking == false && base.contains(location) {
            isTracking = true
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location: CGPoint = touch.location(in: self)
        if isTracking == true {

            let v = CGVector(dx: location.x - base.position.x, dy: location.y - DPad.position.y)
            let angle = atan2(v.dy, v.dx)
            let deg = angle * CGFloat(180 / Double.pi)

            let Length:CGFloat = base.frame.size.height / 2
            let xDist: CGFloat = sin(angle - 1.57079633) * Length
            let yDist: CGFloat = cos(angle - 1.57079633) * Length

            print(xDist,yDist)

            xJoystickDelta = location.x * base.position.x / CGFloat(Double.pi)
            yJoystickDelta = location.y * base.position.y / CGFloat(Double.pi)


            if base.contains(location) {
                thumbNode.position = location
            } else {
                thumbNode.position = CGPoint(x: base.position.x - xDist, y: base.position.y + yDist)
            }

        }

    }

}

Update method

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    if xJoystickDelta > 0 && yJoystickDelta < 0 {
        print("forward")
    }

}

The way I have set up right now tests the positive or negative state of the Joystick position in a cross method based on where the thumb Node is inside of the four marked sections below

image 1

I dont want it to do that

How can I set it up so that it changes the sprite based on where the thumb node is actually pointing inside my joysticks base like so.

image 2

I have been struggling with this for 3 days now so any help would be appreciated.


Solution

  • That looks far too complicated. Just compare the x and y components of the difference vector v. Something like this:

    if v.dx > abs(v.dy) {
        // right
    } else if v.dx < -abs(v.dy) {
        // left
    } else if v.dy < 0 {
        // up
    } else if v.dy > 0 {
        // down
    }