Diagonal controls for on-screen D-Pad

I’m trying to add diagonal controls to my D-Pad. I already have the Up,Down,Left,Right on screen controlling a sprite but I want to implement diagonal top right, diagonal top left , diagonal bottom right and diagonal bottom left. I’ll abbreviate to DTR, DTL, DBR and DBL.

I noticed if I touch Up and swipe my finger to Left it will make the sprite move DTL. Same with touch Up swipe Right moves DTR but it doesn’t work if I touch Left or Right then swipe Top. Vice versa with Down swipe Right and Down swipe Left. You’ll get a better understanding by seeing. The codes below, basically I want a one touch button for each diagonal movement.

function setup()
    --run in landscape mode
    displayMode(FULLSCREEN)
    
    
    rectMode(CENTER)
    b1=vec4(WIDTH/2-70,150,100,50) --button 1 left
    b2=vec4(WIDTH/2+70,150,100,50) --button 2 right
    b3=vec4(WIDTH/2,220,100,50)    --button 3 top
    b4=vec4(WIDTH/2,80,100,50)     --button 4 bottom
    b5=vec4(WIDTH/2-85,HEIGHT*.28,50,50) --button 5 diagonal top left
    b6=vec4(WIDTH/2+85,HEIGHT*.28,50,50) --button 6 diagonal top right
    b7=vec4(WIDTH/2-85,HEIGHT*.11,50,50) --button 7 diagonal bottom left
    b8=vec4(WIDTH/2+85,HEIGHT*.11,50,50) --button 8 diagonal bottom right
    
    
    
    sx,sy=WIDTH/2,HEIGHT/2  -- sprite x,y
    xs=0    -- x speed
    xs2=0
end

function draw()
     
    background(40, 40, 50)       
    
    
    
    
    fill(255)
    rect(b1.x,b1.y,b1.z,b1.w)   -- button 1 left
    rect(b2.x,b2.y,b2.z,b2.w)   -- button 2 right
    rect(b3.x,b3.y,b3.z,b3.w)   -- button 3 top
    rect(b4.x,b4.y,b4.z,b4.w)   -- button 4 bottom
    --Diagonal Buttons
    fill(255, 179, 0)
    ellipse(b5.x,b5.y,b5.z,b5.w)   --button 5 diagonal top left
    ellipse(b6.x,b6.y,b6.z,b6.w)   --button 6 diagonal top right
    ellipse(b7.x,b7.y,b7.z,b7.w)   --button 7 diagonal bottom left
    ellipse(b8.x,b8.y,b8.z,b8.w)   --button 8 diagonal bottom right
    
    
    
    
    fill(255,0,0)
    text("Left",b1.x,b1.y)
    text("Right",b2.x,b2.y)
    text("Top",b3.x,b3.y)
    text("Bottom",b4.x,b4.y)
    text("DTL",b5.x,b5.y)
    text("DTR",b6.x,b6.y)
    text("DBL",b7.x,b7.y)
    text("DBR",b8.x,b8.y)
    
    sprite(asset.builtin.Planet_Cute.Character_Boy,sx,sy,150,150)
    sx=sx+xs
    sy=sy+xs2
        end
    


function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        xs=0
        if t.x>b1.x-b1.z/2 and t.x<b1.x+b1.z/2 and
            t.y>b1.y-b1.w/2 and t.y<b1.y+b1.z/2 then
                xs=-2.2
        end
        if t.x>b2.x-b2.z/2 and t.x<b2.x+b2.z/2 and
            t.y>b2.y-b2.w/2 and t.y<b2.y+b1.z/2 then
                xs=2.2
        end
        
        if t.x>b3.x-b3.z/2 and t.x<b3.x+b3.z/2 and
            t.y>b3.y-b3.w/2 and t.y<b3.y+b1.z/2 then
                xs2=2.2
        end
        if t.x>b4.x-b4.z/2 and t.x<b4.x+b4.z/2 and
            t.y>b4.y-b4.w/2 and t.y<b4.y+b1.z/2 then
                xs2=-2.2
        end  
        
    elseif t.state==ENDED then
        xs=0
        xs2=0
    end
end

@Jarc Maybe you can use this, a joystick type control. Touch the screen anywhere and slide your finger in the direction you want the sprite to go.

displayMode(FULLSCREEN)

function setup()
    cx=WIDTH/2
    cy=HEIGHT/2
    x,y=0,0
    sp=2   -- speed
end

function draw()
    background(40,40,50)
    if x+y>0 then
        cx=cx+(tx-x)/sp
        cy=cy+(ty-y)/sp
    end
    sprite(asset.builtin.Planet_Cute.Character_Boy,cx,cy)
end

function touched(t)
    if t.state==BEGAN then    -- starting center point
        x=t.x
        y=t.y
        tx=x
        ty=y
        lx=x
        ly=y
    elseif t.state==MOVING then
        lx=t.x
        ly=t.y
        v1=vec2(x,y)
        d1=v1:dist(vec2(t.x,t.y))*.7
        tx=t.x
        ty=t.y
        sp=d1/5+1
    elseif t.state==ENDED then    -- done moving
        x,y=0,0
    end
end

@dave1707 That’s kinda what I’m going for. I did some joystick forum searching and I tweaked a joystick code I believe you previously did. Two things I would like to change.

  1. I just want a single sprite on screen, the code makes multiple sprites appear depending on how many fingers are on the screen.
  2. How do I make it so if I touch outside the joystick circle nothing happens aka you stop controlling the sprite.
displayMode(FULLSCREEN)

function setup()
    stab={ 
    readImage("Planet Cute:Character Boy"),
    readImage("Planet Cute:Character Cat Girl"),
    readImage("Planet Cute:Character Pink Girl"),
    readImage("Planet Cute:Character Princess Girl"),
    readImage("Planet Cute:Character Horn Girl")
    }
    rm=-1
    js={}
end

function draw()
    background(40, 40, 50)
    fill(255)
    for a,b in pairs(js) do
        b:draw(a)
   end
end

function touched(t)
    if t.state==BEGAN then
        aa=0
        for a,b in pairs(js) do
            if b.id==0 then
                b.cx=t.x
                b.cy=t.y
                b.id=t.id
                aa=1
                break
            end
        end
        if aa==0 then
            table.insert(js,jst(t.x,t.y,t.id))
        end
    elseif t.state==MOVING or t.state==ENDED then
        for a,b in pairs(js) do
            b:touched(t)
        end
    end
end

jst=class()

function jst:init(cx,cy,id)
    self.cx=cx
    self.cy=cy  
    self.dx=0
    self.dy=0
    self.sx=cx
    self.sy=cy
    self.id=id
end

function jst:draw(a)
    fill(255)
    if self.id>0 then
        fill(255, 255, 255, 50)
        ellipse(self.cx,self.cy,8) -- draw circle center
        fontSize(15)
        fill(233, 80, 133)
        text("Up",self.cx,self.cy+80)
        text("Down",self.cx,self.cy-80)
        text("Right",self.cx+80,self.cy)
        text("Left",self.cx-80,self.cy)
        fontSize(10)
        text("DTL",self.cx-60,self.cy+60)
        text("DTR",self.cx+60,self.cy+60)
        text("DBL",self.cx-60,self.cy-60)
        text("DBR",self.cx+60,self.cy-60)
        noFill()
        stroke(255,255,255,50)
        strokeWidth(4)
        ellipse(self.cx,self.cy,200) -- draw outer circle     
    end 
    self.sx=self.sx+self.dx
    self.sy=self.sy+self.dy
    sprite(stab[a%5+1],self.sx,self.sy)
    
end

function jst:touched(t)
    if t.state==MOVING then
        if self.id==t.id then
            self.dx=(t.x-self.cx)/10
            self.dy=(t.y-self.cy)/10
        end
    end
    if t.state==ENDED then
        if self.id==t.id then
            rm=t.id
            self.id=0
            self.dx=0
            self.dy=0
            self.cx=0
            self.cy=0
        end
    end   
end

Try this. If you have questions, just post.

displayMode(FULLSCREEN)

function setup()
    pic=readImage("Planet Cute:Character Boy")
    cx,cy=WIDTH/2,150
    sx,sy=WIDTH/2,HEIGHT/2
    dx,dy=0,0
end

function draw()
    background(40, 40, 50)
    drawCirc()
    sx=sx+dx
    sy=sy+dy
    sprite(pic,sx,sy)
end

function touched(t)
    if t.x>cx-80 and t.x<cx+80 and t.y>cy-8000 and t.y<cy+80 then
        if t.state==MOVING or t.state==ENDED then
            dx=(t.x-cx)/10
            dy=(t.y-cy)/10
        end
    end
    if t.state==ENDED then
        dx,dy=0,0
    end
end

function drawCirc()
    fill(255, 255, 255, 50)
    ellipse(cx,cy,8) -- draw circle center
    fontSize(15)
    fill(233, 80, 133)
    text("Up",cx,cy+80)
    text("Down",cx,cy-80)
    text("Right",cx+80,cy)
    text("Left",cx-80,cy)
    fontSize(10)
    text("DTL",cx-60,cy+60)
    text("DTR",cx+60,cy+60)
    text("DBL",cx-60,cy-60)
    text("DBR",cx+60,cy-60)
    noFill()
    stroke(255,255,255,50)
    strokeWidth(4)
    ellipse(cx,cy,200) -- draw outer circle     
end

@dave1707 other than these adjustments it’s almost there.

changed this

if t.x>cx-80 and t.x<cx+80 and t.y>cy-8000 and t.y<cy+80 then

to

if t.x>cx-80 and t.x<cx+80 and t.y>cy-80 and t.y<cy+80 then

I still want the joystick to appear anywhere on screen and to only appear when I’m touching the screen, like in the code before.

@Jarc Sorry, I didn’t notice the 8000 when I made changes. So, you want the circle to appear anywhere on the screen when touched, and you want it to stop working if you’re outside the circle.

@dave1707 Correct. Meaning it disappears when you lift your finger off the screen. It also disappears if you go outside joystick circle.

I added code to check if touch is inside of a circle instead of a square inside the circle.

displayMode(FULLSCREEN)

function setup()
    pic=readImage("Planet Cute:Character Boy")
    cx,cy=0,0
    sx,sy=WIDTH/2,HEIGHT/2
    dx,dy=0,0
end

function draw()
    background(40, 40, 50)
    if cx>0 and cy>0 then
        drawCirc()
    end
    sx=sx+dx
    sy=sy+dy
    sprite(pic,sx,sy)
end

function touched(t)
    if t.state==BEGAN then
        cx,cy=t.x,t.y      
    end
    if t.state==MOVING then
        if insideCircle(t.x,t.y) then
            dx=(t.x-cx)/10
            dy=(t.y-cy)/10
        else
            cx,cy=0,0
            dx,dy=0,0
        end
    end
    if t.state==ENDED then
        cc,cy=0,0
        dx,dy=0,0
    end
end

function insideCircle(x,y)
    -- check if touch is inside of circle or ellipse
    a,b=100,100 -- radius of circle or a,b of ellipse
    if (x-cx)^2/a^2+(y-cy)^2/b^2 <= 1 then 
        return true
    end
    return false
end

function drawCirc()
    fill(255, 255, 255, 50)
    ellipse(cx,cy,8) -- draw circle center
    fontSize(15)
    fill(233, 80, 133)
    text("Up",cx,cy+80)
    text("Down",cx,cy-80)
    text("Right",cx+80,cy)
    text("Left",cx-80,cy)
    fontSize(10)
    text("DTL",cx-60,cy+60)
    text("DTR",cx+60,cy+60)
    text("DBL",cx-60,cy-60)
    text("DBR",cx+60,cy-60)
    noFill()
    stroke(255,255,255,50)
    strokeWidth(4)
    ellipse(cx,cy,200) -- draw outer circle     
end

@dave1707 That’s exactly right and done swiftly. Thanks Dave!