Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Joystick problem

edited June 27 in Bugs Posts: 12

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.

Tagged:

Comments

  • edited June 27 Posts: 12

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

  • dave1707dave1707 Mod
    Posts: 5,896

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

  • dave1707dave1707 Mod
    edited June 27 Posts: 5,896

    @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.

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • Posts: 12

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

  • edited June 27 Posts: 12

    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
  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • dave1707dave1707 Mod
    edited June 30 Posts: 5,896

    @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
    
  • Posts: 12

    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?

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • Posts: 12

    Thank you

  • Posts: 12

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

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • Posts: 12

    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?

  • dave1707dave1707 Mod
    Posts: 5,896

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

  • dave1707dave1707 Mod
    Posts: 5,896

    @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.

  • dave1707dave1707 Mod
    Posts: 5,896

    @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
    
  • Posts: 12

    Yesssss, thank you.

  • edited July 2 Posts: 12

    I now have another problem. When I type this:

        r.x=100
        r.xSize=100
        r.y=100
        r.ySize=100
    r=physics.body(POLYGON,vec2(rx,ry),vec2(rx+rxSize,ry),vec2(rx,ry+rySize),vec2(rx+rxSize,ry+rySize))
    

    It says there is an error. What did I do wrong?

  • dave1707dave1707 Mod
    Posts: 5,896

    @Flappie You have to define the physics body before you can start assigning values to its variables.

  • dave1707dave1707 Mod
    Posts: 5,896

    Here's an example of defining a polygon.

    displayMode(FULLSCREEN)
    
    function setup()
        floor=physics.body(EDGE,vec2(0,20),vec2(WIDTH,20))
        floor.type=STATIC
        floor.x=0
        floor.y=0   
    
        p=physics.body(POLYGON,vec2(0,-100),vec2(0,100),vec2(50,100),vec2(50,-100))
        p.x=WIDTH/2
        p.y=600
        p.angle=58
        p.restitution=0.7
    end
    
    function draw()
        background(0)
        stroke(255)
        strokeWidth(2)
        line(0,20,WIDTH,20)
        polygon(p)
    end
    
    function polygon(p)
        pushMatrix()
        translate(p.x, p.y)
        rotate(p.angle)
        for i = 1, #p.points do
            local a = p.points[i]
            local b = p.points[(i % #p.points)+1]
            line(a.x, a.y, b.x, b.y)
        end
        popMatrix()
    end
    
  • Posts: 12

    Is it also possible to have variables for the polygon instead of typing it in manually?

  • dave1707dave1707 Mod
    Posts: 5,896

    You can have variables, but the variables then need values to define the shape of the polygon.

Sign In or Register to comment.