Joysticks! My first project ever.

This here is a joystick class which, while horribly inefficient (cut me some slack, it’s my first project ever!), is rather easy to use and implement into other projects. I am aware it is sloppy but with some tinkering most parts of it can be easily changed:

Joystiqs = class()

touch = nil
originx = nil
originy = nil
originid = nil
touch2 = nil
originx2 = nil
originy2 = nil
originid2 = nil

function Joystiqs:init()
end

function Joystiqs:draw()
    background(0, 0, 0, 255)
    stroke(127, 127, 127, 25)
    strokeWidth(0)
    lineCapMode(SQUARE)
    self:j1Calc()
    self:j2Calc()
    self:cleanJoystickData()
end

function Joystiqs:touched(touched)
    if touched.x < WIDTH/2 and touch == nil and touched.state == BEGAN then
        touch = touched
        originid = touched.id
        originx = touched.x
        originy = touched.y  
    elseif touch ~= nil and  touched.id == originid then
        touch = touched 
    end
    
    if (touched.state == ENDED) and (touched.id == originid) then
        touch = nil
        originx = nil
        originy = nil
        originid= nil
    end
    
    if touched.x > WIDTH/2 and touch2 == nil and touched.state == BEGAN then
        touch2 = touched
        originid2 = touched.id
        originx2 = touched.x
        originy2 = touched.y  
    elseif touch2 ~= nil and  touched.id == originid2 then
        touch2 = touched 
    end
    
    if (touched.state == ENDED) and (touched.id == originid2) then
        touch2 = nil
        originx2 = nil
        originy2 = nil
        originid2 = nil
    end
    
end

function Joystiqs:j1Calc()
     
    if (touch ~= nil) then
        offsetx = touch.x - originx
        offsety = touch.y - originy
        preangle = (math.atan((offsety)/(offsetx)))
            if offsetx == 0 and offsety > 0 then
                angle = math.pi/2
            else
                if offsetx <= 0 and offsety > 0 then
                    angle = math.pi + preangle
                elseif offsetx < 0 and offsety <= 0 then
                    angle = math.pi + preangle
                elseif offsetx >=0 and offsety < 0 then
                    angle = (2*math.pi) + preangle
                else
                    angle = preangle
                end
            end
            if math.sqrt((offsetx*offsetx)+(offsety*offsety)) > 75 then
                linelimiterx = (75*math.cos(angle)) + originx
                linelimitery = (75*math.sin(angle)) + originy
            else
                linelimiterx = touch.x 
                linelimitery = touch.y
            end
        magnitude = math.sqrt(((linelimiterx-originx)^2)+((linelimitery-originy)^2))
        fill(255, 255, 255, 100)
        ellipse(originx, originy, 150)
        line(originx, originy, linelimiterx, linelimitery)
        fill(0, 0, 0, 100)
        ellipse(linelimiterx, linelimitery, 150)
        if magnitude < 25 and magnitude >10 then
            magnitude = 0
        elseif magnitude <= 10 then
            magnitude = 0
            angle = nil
        else
            magnitude = magnitude - 25
        end
    end
    
end

function Joystiqs:j2Calc()
    
    if (touch2 ~= nil) then
        offsetx2 = touch2.x - originx2
        offsety2 = touch2.y - originy2
        preangle2 = (math.atan((offsety2)/(offsetx2)))
            if offsetx2 == 0 and offsety2 > 0 then
                angle2 = math.pi/2
            else
                if offsetx2 <= 0 and offsety2 > 0 then
                    angle2 = math.pi + preangle2
                elseif offsetx2 < 0 and offsety2 <= 0 then
                    angle2 = math.pi + preangle2
                elseif offsetx2 >=0 and offsety2 < 0 then
                    angle2 = (2*math.pi) + preangle2
                else
                    angle2 = preangle2
                end
            end
            if math.sqrt((offsetx2*offsetx2)+(offsety2*offsety2)) > 75 then
                linelimiterx2 = (75*math.cos(angle2)) + originx2
                linelimitery2 = (75*math.sin(angle2)) + originy2
            else
                linelimiterx2 = touch2.x 
                linelimitery2 = touch2.y
            end
        magnitude2 = math.sqrt(((linelimiterx2-originx2)^2)+((linelimitery2-originy2)^2))
        fill(255, 255, 255, 100)
        ellipse(originx2, originy2, 150)
        line(originx2, originy2, linelimiterx2, linelimitery2)
        fill(0, 0, 0, 100)
        ellipse(linelimiterx2, linelimitery2, 150)
        if magnitude2 < 25 and magnitude2 > 10 then
            magnitude2 = 0
        elseif magnitude2 < 10
            magnitude2 = 0
            angle2 = nil
        else
            magnitude2 = magnitude2 - 25
        end
    end
    
end

function Joystiqs:cleanJoystickData()
    offsetx=nil
    offsety=nil
    offsetx2=nil
    offsety2=nil
    preangle=nil
    preangle2=nil
    angle=nil
    angle2=nil
    linelimiterx=nil
    linelimitery=nil
    linelimiterx2=nil
    linelimitery2=nil
    magnitude=nil
    magnitude2=nil  
end

@Monkeyman32123 - nice work!

You might want to make all the variables you declare at the beginning, local (especially “touch”, which is commonly used in Codea). If you make them local, then they only exist in the current code tab, so if you put this class in its own tab, then they won’t affect any code in other tabs. You should also make the other variables you use, like offsetx, local, as well, so they don’t mess up a user’s other code.

It helps to give a little example, or maybe a video, if you want to show how it gets used. That may encourage more people to try it out.

You will probably find several other examples in the forum if you search, which is useful.

Below is one that Andrew_Stacey wrote recently. It returns an x and y value between -1 and +1. The interesting part is the update function, which smooths the movement of the joystick by interpolation. It needs to be run in the draw function to update it.

JoyStick = class()

function JoyStick:init(t)
    t = t or {}
    self.radius = t.radius or 100
    self.stick = t.stick or 30
    self.centre = t.centre or self.radius * vec2(1,1) + vec2(5,5)
    self.position = vec2(0,0)
    self.target = vec2(0,0)
    self.value = vec2(0,0)
    self.delta = vec2(0,0)
    self.mspeed = 60
    self.moving = 0
end

function JoyStick:draw()
    -- Codea does not automatically call this method
    pushStyle()
    fill(160, 182, 191, 50)
    stroke(118, 154, 195, 100)
    strokeWidth(1)
    ellipse(self.centre.x,self.centre.y,2*self.radius)
    fill(78, 131, 153, 50)
    ellipse(self.centre.x+self.position.x, self.centre.y+self.position.y, self.stick*2)
    popStyle()
end

function JoyStick:touched(t)
    if t.state == BEGAN then
        local v = vec2(t.x,t.y)
        if v:dist(self.centre)<self.radius-self.stick then
            self.mytouch = t.id
        end
    end
    if t.id == self.mytouch then
        if t.state~=ENDED then
            local v = vec2(t.x,t.y)
            if v:dist(self.centre)>self.radius-self.stick then
                v = (v - self.centre):normalize()*(self.radius - self.stick) + self.centre
            end --set x,y values for joy based on touch
            self.target=v - self.centre
        else --reset joystick to centre when touch ends
            self.target=vec2(0,0)
            self.mytouch = false
        end
    end
end

function JoyStick:update()
    local p = self.target - self.position
    if p:len() < DeltaTime * self.mspeed then
        self.position = self.target
        if not self.mytouch then
            if self.moving ~= 0 then
                self.moving = self.moving - 1
            end
        else
            self.moving = 2
        end
    else
        self.position = self.position + p:normalize() * DeltaTime * self.mspeed
        self.moving = 2
    end
    local v = self.position/(self.radius - self.stick)
    self.delta = v - self.value
    self.value = v
end
 
function JoyStick:isMoving()
    return self.moving
end

Thanks for the tips! I’m pretty new to the whole coding scene, and since I’m teaching myself I didn’t really know what local was used for (heck, I don’t know what a lot of things are used for). But I will keep that in mind from now on ^-^

@Monkeyman32123 - try some tutorials, see the wiki link above.

I also have heaps of stuff here

http://coolcodea.wordpress.com/2013/06/19/index-of-posts/