Joystick problem

I have a small problem with my joystick.
I have a joystick but the knob of the joystick sometimes doesn’t go all the way to the edge.
Does anyone know how to solve it
Here is my code:

-- Joystick Test
displayMode(FULLSCREEN)
-- Use this function to perform your initial setup
function setup()
    print("Hello World!")
    joystick = {x, y, xMin, xMax, yMin, yMax, size}
    joystick.x = -100
    joystick.y = -100
    joystick.xMin = 0
    joystick.xMax = 250
    joystick.yMin = 0
    joystick.yMax = 250
    joystick.size = 140
    joystickKnob = {x, y, size}
    joystickKnob.x = -100
    joystickKnob.y = -100
    joystickKnob.size = 110
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness

    -- Do your drawing here
    fill(0, 0, 0, 255)
    strokeWidth(5)
    ellipse(joystick.x, joystick.y, joystick.size)
    fill(255, 255, 255, 255)
    strokeWidth(0)
    ellipse(joystickKnob.x, joystickKnob.y, joystickKnob.size)
    
end

function touched(touch)
    if touch.state == BEGAN and touch.x < joystick.xMax and touch.x > joystick.xMin and touch.y < joystick.yMax and touch.y > joystick.yMin
    then
        joystick.x = touch.x
        joystick.y = touch.y
        joystickKnob.x = touch.x
        joystickKnob.y = touch.y
    end
    if touch.state == MOVING
    then
        if touch.x < joystick.x + joystick.size/2  - joystickKnob.size/2 and touch.x > joystick.x - joystick.size/2 + joystickKnob.size/2
        then
            joystickKnob.x = touch.x
        end
        if touch.y < joystick.y + joystick.size/2  - joystickKnob.size/2 and touch.y > joystick.y - joystick.size/2 + joystickKnob.size/2
        then
            joystickKnob.y = touch.y
        end
    end
    if touch.state == ENDED
    then
        joystick.x = -100
        joystick.y = -100
        joystickKnob.x = -100
        joystickKnob.y = -100
    end
end

The code isn’t but the best but I tried.

no clue how to have the code in the box thing. sorry

@Flappie To show code correctly, put 3 ~'s on a line by themselves before and after the code.

@Flappie I can’t recreate the problem you’re having. Can you give more info of how to create your problem. The inner circle always touches the outer circle for me.

EDIT: Nevermind, I see what’s happening.

@Flappie The problem I see is if you slide your finger too fast going outside the inner circle, then you’re not capturing the value of touch. You need to increase the touch area of the inner circle.

@dave1707 So what I need to do is add is a little more margin to the inner circle?

I added a margin of 10


margin = 10

if touch.state == BEGAN and touch.x < joystick.xMax + **margin** and touch.x > joystick.xMin - **margin** and touch.y < joystick.yMax + **margin** and touch.y > joystick.yMin - **margin**
    then
        joystick.x = touch.x
        joystick.y = touch.y
        joystickKnob.x = touch.x
        joystickKnob.y = touch.y
    end
    if touch.state == MOVING
    then
        if touch.x < joystick.x + joystick.size/2  - joystickKnob.size/2  + **margin** and touch.x > joystick.x - joystick.size/2 + joystickKnob.size/2 - **margin**
        then
            joystickKnob.x = touch.x
        end
        if touch.y < joystick.y + joystick.size/2  - joystickKnob.size/2 + **margin** and touch.y > joystick.y - joystick.size/2 + joystickKnob.size/2 - **margin**
        then
            joystickKnob.y = touch.y
        end
    end

@Flappie The margin doesn’t solve the problem. It just allows the inner circle to go beyond the outer circle. You still have the problem that if you move your finger too fast, it doesn’t get the latest x,y values to move the inner circle far enough. You need to rethink how you move the inner circle.

@Flappie One thing you can try is to accept any x,y values even beyond the outer circle, but limit the position of the inner circle to not go beyond the outer circle.

@Flappie Here’s a joystick example based on what I said above. The inner circle moves within the outer circle no matter where the moving finger is. Touch anywhere on the screen to display the joystick to move the sprite.

displayMode(FULLSCREEN)

function setup()
    inner=80    -- size of inner circle
    outer=200   -- size of outer circle
    diff=outer/2-inner/2
    sx,sy=WIDTH/2,HEIGHT/2
    spx,spy=0,0
end

function draw()
    background(40, 40, 50)
    sprite("Planet Cute:Character Horn Girl",sx,sy)
    js()
end

function js()
    if show then
        v1=vec2(cx,cy)
        d=v1:dist(vec2(x,y))    -- distance from center to touch point
        if d<diff then      -- touch is within outer circle
            px,py=x,y
        else
            a=diff/d     -- touch is outside outer circle
            px=(x-cx)*a+cx     -- calculate inner circle position
            py=(y-cy)*a+cy
        end
        stroke(255)
        strokeWidth(4)
        noFill()
        ellipse(cx,cy,outer)     -- draw outer circle
        fill(255)
        ellipse(px,py,inner)     -- draw inner circle   
        v1=vec2(px,py)
        d1=v1:dist(vec2(cx,cy))     -- determine distance to calculate speed 
        sp=d1/4+1 
        spx=(px-cx)/sp
        spy=(py-cy)/sp         
        sx=sx+spx    -- calculate x speed of Sprite 
        sy=sy+spy    -- calculate y speed of Sprite
    elseif math.abs(spx+spy)>.1 then
        spx=spx*.98 -- slow the sprite 
        spy=spy*.98
        sx=sx+spx
        sy=sy+spy
    end      
end

function touched(t)
    if t.state==BEGAN then  -- get beginning touch points
        cx,cy=t.x,t.y
        x,y=cx,cy
        show=true   -- set to show joystick
    end
    if t.state==MOVING then   -- get moving touch points
        x,y=t.x,t.y
    end
    if t.state==ENDED then   -- stop showing joystick
        show=false
    end
end

I’m not a very good programmer so I don’t know what it does. So could you tell me how it works and what it does?

@Flappie I added comments to my above program. As you get more experience at coding, reading other people’s code will get easier to understand.

Thank you

Another question: How do you make it slow down instead of instantly stopping when released? Thank you in advance

@dave1707

@Flappie Sorry, I got distracted by other things and forgot about your question. Thanks for reminding me. I changed my code above to slow the Sprite instead of stopping it once the joystick is released.

Now when you jerk the joystick from one side to the other it doesn’t have a nice transistion. How do you make it slow down and then go to the other side?

@Flappie That’s going to be a bit harder.

@Flappie Actually, the easiest way would be to switch the Sprite to use a physics object and use acceleration to vary the speed and direction. How much do you know about the physics engine.

@Flappie Here’s a version that uses the physics engine. This works the way you were describing, but I’m not sure how well.

displayMode(FULLSCREEN)

function setup()
    physics.continuous=true
    inner=80    -- size of inner circle
    outer=200   -- size of outer circle
    diff=outer/2-inner/2
    lvx,lvy=0,0
    p=physics.body(CIRCLE,0)
    p.x=WIDTH/2
    p.y=HEIGHT/2
    p.gravityScale=0
    p.linearDamping=1.5
end

function draw()    
    background(40, 40, 50)
    sprite("Planet Cute:Character Horn Girl",p.x,p.y)
    js()
end

function js()
    if show then
        v1=vec2(cx,cy)
        d=v1:dist(vec2(x,y))    -- distance from center to touch point
        if d<diff then      -- touch is within outer circle
            px,py=x,y
        else
            a=diff/d     -- touch is outside outer circle
            px=(x-cx)*a+cx     -- calculate inner circle position
            py=(y-cy)*a+cy
        end
        stroke(255)
        strokeWidth(4)
        noFill()
        ellipse(cx,cy,outer)     -- draw outer circle
        fill(255)
        ellipse(px,py,inner)     -- draw inner circle   
        lvx=lvx+(px-cx)/15
        lvy=lvy+(py-cy)/15
        p.linearVelocity=vec2(lvx,lvy)
    end      
end

function touched(t)
    if t.state==BEGAN then  -- get beginning touch points
        cx,cy=t.x,t.y
        x,y=cx,cy
        lvx=p.linearVelocity.x
        lvy=p.linearVelocity.y
        show=true   -- set to show joystick
    end
    if t.state==MOVING then   -- get moving touch points
        x,y=t.x,t.y
    end
    if t.state==ENDED then   -- stop showing joystick
        show=false
        lvx,lvy=0,0
    end
end