Here is mine, with some simple demo code
--# Main
-- Joy
-- Use this function to perform your initial setup
function setup()
--simple version, accepts all default settings
joy=JoyStick()
--uncomment the next 2 lines to change some defaults, note the table layout
--joySettings={centre=vec2(WIDTH-110,100),innerColor=color(255, 0, 229),outerColor=color(202, 144, 118)}
--joy=JoyStick(joySettings)
velocity=vec2(0,0)
pos=vec2(WIDTH/2,HEIGHT/2)
end
function draw()
background(138, 193, 202, 255)
--update joystick and return vec2 with x,y values between -1 and +1
delta=joy:update()
velocity=velocity+delta/20 --adjust velocity by up to 1/20 pixels/sec in any direction
pos=pos+velocity
fill(255,255,0)
ellipse(pos.x,pos.y,40)
joy:draw()
end
function touched(t)
--process touches on joystick
joy:touched(t)
end
--# Joystick
--Controls
--contains Joystick controls
JoyStick = class()
--Note all the options you can set below. Pass them through in a named table
function JoyStick:init(t)
t = t or {}
self.radius = t.radius or 100 --size of joystick on screen
self.stick = t.stick or 30 --size of inner circle
self.centre = t.centre or self.radius * vec2(1,1) + vec2(5,5)
self.damp=t.damp or vec2(0.1,0.1)--dampens speed of return to centre of joystick when finger lifts
self.lineColor=t.lineColor or color(0,0,0,25)
self.outerColor=t.outerColor or color(188, 195, 219, 100)
self.innerColor=t.innerColor or color(114, 133, 199, 125)
self.position = vec2(0,0) --initial position of inner circle
self.target = vec2(0,0) --current position of inner circle (used when we interpolate movement)
self.value = vec2(0,0)
self.delta = vec2(0,0)
self.mspeed = 30
self.moving = 0
self.tick=1/60 --time between joystick updates
end
function JoyStick:draw()
ortho()
viewMatrix(matrix())
pushStyle()
fill(self.outerColor)
stroke(self.lineColor)
strokeWidth(3)
ellipse(self.centre.x,self.centre.y,2*self.radius)
fill(self.innerColor)
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.touch = t.id
--else return false
end
end
if t.id == self.touch 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.touch = false
end
else return false
end
return true
end
function JoyStick:update()
local p = self.target - self.position
if p:len() < self.tick * self.mspeed then
self.position = self.target
if not self.touch then
if self.moving ~= 0 then
self.moving = self.moving - 1
end
else
self.moving = 2
end
else
self.position = self.position + p:normalize() * self.tick * self.mspeed
self.moving = 2
end
local v=self.position/(self.radius - self.stick)
return self:Dampen(v)
end
function JoyStick:Dampen(v)
if not self.damp then return v end
if v.x>0 then v.x=math.max(0,(v.x-self.damp.x)/(1-self.damp.x))
else v.x=math.min(0,(v.x+self.damp.x)/(1-self.damp.x)) end
if v.y>0 then v.y=math.max(0,(v.y-self.damp.y)/(1-self.damp.y))
else v.y=math.min(0,(v.y+self.damp.y)/(1-self.damp.y)) end
return v
end
function JoyStick:isMoving()
return self.moving
end
function JoyStick:isTouched()
return self.touch
end