Utility On-Screen Controls Library

Hello all!
Thought I would just take a moment to share what I’ve been working on. It is a collection of classes(at this point only one, but there will be more) that add different control mechanisms for games into codea. So far there is only a joystick, but I expect to implement buttons and other types of controls shortly. If you have any ideas for new controls, please post below! Here is the code:

--# CircleJoystick
CircleJoystick = class()

function CircleJoystick:init(x,y,mode)
    -- you can accept and set parameters here
    self.x = x
    self.y = y
    self.mode = mode
    self.joy=vec2(x,y)
    self.tId=nil
    self.touches={}
end

function CircleJoystick:draw()
    -- Codea does not automatically call this method
    noStroke()
    fill(255, 255, 255, 255)
    ellipse(self.x,self.y,100,100)
    stroke(211, 211, 211, 255)
    strokeWidth(20)
    line(self.x, self.y, self.joy.x, self.joy.y)
    noStroke()
    fill(255, 0, 0, 255)
    ellipse(self.joy.x, self.joy.y, 50, 50)
    
    for i,v in pairs(self.touches) do
        if vec2(v.x,v.y):dist(vec2(self.x,self.y))<=50 and v.state~=ENDED then
            self.tId=i
        end
    end
    if self.tId~=nil then
        if vec2(self.touches[self.tId].x, self.touches[self.tId].y):dist(vec2(self.x,self.y))>=50 then
        self.dif=vec2(self.touches[self.tId].x, self.touches[self.tId].y)-vec2(self.x,self.y)
        self.dif=self.dif:normalize()
        self.returnAValue=self.dif
        self.joy=self.dif*50+vec2(self.x,self.y)
        else self.joy.x, self.joy.y=self.touches[self.tId].x, self.touches[self.tId].y 
        end
        if self.touches[self.tId].state==ENDED then
            self.tId=nil
            self.joy=vec2(self.x,self.y)
            self.returnAValue=vec2(0,0)
            self.returnRValue=0
        else
self.returnRValue=math.deg(math.atan2(self.x-self.touches[self.tId].x,self.y-self.touches[self.tId].y))+180
        end
    end
    if self.returnAValue==nil then
        self.returnAValue=vec2(0,0)
    end
    if self.returnRValue==nil then
        self.returnRValue=0
    end
    if self.mode==1 then
        return self.returnAValue
    end
    if self.mode==2 then
        return -self.returnRValue
    end
end

function CircleJoystick:touched(t)
    -- Codea does not automatically call this method
    self.touches[t.id]=t
end

--# Main
-- My Project

-- Use this function to perform your initial setup
function setup()
    print("Hello World!")
    touches={}
    j=CircleJoystick()
    j:init(100, 100, 1)
    jj=CircleJoystick()
    jj:init(WIDTH-100, 100, 2)
    pos=vec2(0,0)
    vel=vec2(0,0)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 40)
    add=j:draw()
    pos=pos+add*8
    r=jj:draw()
    pushMatrix()
    translate(pos.x,pos.y)
    rotate(r)
    print(r)
    sprite("Space Art:Green Ship",0,0, 50, 50)
    popMatrix()
end

function touched(t)
    j:touched(t)
    jj:touched(t)
end

Note-I have added some extra code in the main tab just to demonstrate the functionality of the joystick. Basically it has 2 modes, one returns the normalized vector between the touch and the joystick(1) and the other returns the angle between the joystick and the touch(2). These can be used in any games, just please give me credit! Thank you. Also, I used the main tab to demonstrate how different instances of the class can be made to make multiple joysticks. Thanks for reading!

very nice.

In the setup you could have put the init parameters as params to the first call to circlejoystick.