I was really bored, so I thought I would make something for fun. I also haven’t posted code in a while. So, here is a wheel, I commented it sort of like a tutorial!
--# Main
-- Wheel
function setup()
w=Wheel(
{x=WIDTH/2,y=HEIGHT/2,size=300},--The Basic Args
--Insert all the items
{
{col=color(255, 0, 0, 169),txt="CODEA!",img="Cargo Bot:Codea Icon"},
{col=color(0, 255, 0, 167),txt="$$$",img="Cargo Bot:Dialogue Box"},
{col=color(0, 0, 255, 170),txt="Wheel of\
Fortune",callback=function(i,v)
print("The circle has rotated "..w.rotation.."\\u{00B0}")end},
{col=color(255, 123, 0, 255),txt="This is Orange!"},
},
--Middle Button Args
{callback=function()w:spin(50)end}
)
--Parameters
parameter.integer("Position of arrow on the wheel",0,360,w.arrowDirection,function(n)w.arrowDirection=n end)
parameter.number("Drag of the wheel",0.5,1,w.drag,function(n)w.drag=n end)
parameter.action("Hide/Show Spin Button",function()if not w.middleButton.hidden then w.middleButton.hide()
else w.middleButton.show() end end)
parameter.color("Color_Of_Pointing",nil)
end
-- This function gets called once every frame
function draw()
background(255, 255, 255, 255)
w:draw()
end
function touched(t)
w:touched(t)
end
--# Wheel
--Wheel.lua
--This class is supposed to give you a wheel which is constructed of multiple arrays of data. The wheel can spin and indicate where it landed
--Why did I make this many of you may be asking, because I'm bored, that's why!
Wheel = class()
function Wheel:init(args,items,middle)
--Basic args
self.x=args.x or 0
self.y=args.y or 0
self.size=args.size or 100
--Arcs
self.arcs={}
self.itemCheckData={}
self.items=items or {}
for i,item in ipairs(self.items) do
--Starting degree measure for the arc
local s=360*(i-1)/#items
--Ending degree measure for the arc
local e=360*i/#items
--Just used for the getPointer method
table.insert(self.itemCheckData,{start=s,e_nd=e})
--Make the arc!
table.insert(self.arcs,Arc(0,0,self.size,s,e,item.col or color(0,0,0,0)))
end
--Rotation Args
--The overall rotation
self.rotation=0
--The spinning variable
self.extraRotate=0
--How slow to decrease the speed of the spinning wheel
self.drag=args.drag or 0.982
--When to check if the circle is done spinning
self.endCheck=args.endCheck or 0.05
--Pointer
--Where the arrow is pointing at, 0-360 degree measures
self.arrowDirection=(args.arrowDirection or 90)%360
--Setup the vertices
self.pointerMesh=mesh()
self.pointerMesh.vertices={
vec2(-20,self.size+10),
vec2(20,self.size+10),
vec2(0,self.size-40),
}
--I couldn't really find any good colors
self.pointerMesh.colors={color(255,0,0),color(255,0,0),color(127, 127, 127, 145)}
--Middle Spin Button
self.middleButton={txt="SPIN",font="HelveticaNeue-Bold",btnSize=100,txtCol=color(255),
callback=function()self:spin(10)end,shouldDraw=true,selectable=true,btnCol=color(0,249,255,255),
hide=function()if not self.middleButton.hidden then
tween(1,self.middleButton,{btnSize=0},tween.easing.elasticInOut,
function()self.middleButton.hidden=true end)
end end,
show=function()if self.middleButton.hidden then
tween(1,self.middleButton,{btnSize=self.middleButton.originalBtnSize},tween.easing.bounceIn,
function()self.middleButton.hidden=false end)
end
end}
self.middleButton.originalBtnSize=self.middleButton.btnSize
for i,v in pairs(middle or {}) do
self.middleButton[i]=v
end
end
function Wheel:draw()
self:drawArcs()
self:labelArcs()
if self:isSpinning() then self:rotate()end
self:drawSpinButton()
end
function Wheel:drawArcs()
pushMatrix()
translate(self.x,self.y)
rotate(self.rotation)
for i,arc in ipairs(self.arcs) do
arc:draw()
end
rotate(-self.rotation+self.arrowDirection-90)
self.pointerMesh:draw()
popMatrix()
end
function Wheel:labelArcs()
for i,item in ipairs(self.items) do
pushMatrix()
pushStyle()
translate(self.x,self.y)
rotate((self.itemCheckData[i].start+self.itemCheckData[i].e_nd)/2-90+self.rotation)
local pos=vec2(0,self.size*7/10)
if item.txt then
fill(0, 0, 0, 255)
font("HoeflerText-Black")
textWrapWidth(self.size*4/#self.items)
fontSize(self.size*3/5/#self.items)
textAlign(CENTER)
textMode(CENTER)
if item.img then
pos=vec2(0,self.size*6/8)
end
pos.y = pos.y + (70-self.middleButton.originalBtnSize)
text(item.txt,pos:unpack())
end
if item.img then
spriteMode(CENTER)
if item.txt then
pos=vec2(0,self.size*4/8)
end
pos.y = pos.y + (70-self.middleButton.originalBtnSize)
sprite(item.img,pos.x,pos.y,100*5/#self.items,100*5/#self.items)
end
popStyle()
popMatrix()
end
end
function Wheel:drawSpinButton()
if not self.middleButton.shouldDraw then return end
pushStyle()
pushMatrix()
translate(self.x,self.y)
ellipseMode(CENTER)
fill(0)
local c=self.middleButton.btnCol;c.a=100
stroke(c)
strokeWidth(self.middleButton.btnSize*0.05)
ellipse(0,0,self.middleButton.btnSize,self.middleButton.btnSize)
noStroke()
c.a=255;fill(c)
ellipse(0,0,self.middleButton.btnSize*0.8,self.middleButton.btnSize*0.8)
fill(0, 0, 0, 255)
fontSize(self.middleButton.btnSize/4)
font(self.middleButton.font)
textAlign(CENTER)
textMode(CENTER)
text(self.middleButton.txt,-1,-1)
fill(self.middleButton.txtCol)
text(self.middleButton.txt)
popMatrix()
popStyle()
end
function Wheel:rotate()
self.rotation = self.rotation + self.extraRotate
self.extraRotate = self.extraRotate * self.drag
if self.extraRotate<self.endCheck then
self.landedOn=self:getPointer()
self.extraRotate=0
if self.items[self.landedOn].callback then
self.items[self.landedOn].callback(self.landedOn,self.items[self.landedOn])
end
print(self.items[self.landedOn].txt)
Color_Of_Pointing=self.items[self.landedOn].col
end
end
function Wheel:touched(t)
local sc=97/100
local mult=1
local function enlarge()self.middleButton.btnSize = self.middleButton.btnSize * math.pow(sc,-1)end
if (t.x-self.x)^2 +(t.y-self.y)^2<=self.middleButton.btnSize^2 then
if self.middleButton.shouldDraw and self.middleButton.selectable and not self:isSpinning() then
if t.state==ENDED then
enlarge()
self.middleButton.selected=nil
self.middleButton.callback()
--self.middleButton.hide()
elseif t.state==BEGAN then
self.middleButton.selected=true
self.middleButton.btnSize = self.middleButton.btnSize * sc
end
end
elseif t.state==MOVING and self.middleButton.selected then
enlarge()
self.middleButton.selected=false
end
if self.middleButton.selected and t.state==ENDED then
enlarge()
end
end
function Wheel:isSpinning()return self.extraRotate>0 end
function Wheel:getPointer()
for i,v in ipairs(self.itemCheckData) do
local pert=360/#self.items
local check=self.arrowDirection
local s=(v.start+self.rotation)%360
local e=(v.e_nd+self.rotation)%360
::check::
if s<=check and e>check then
return i
else
local per=pert*2
if 360-s<=per/2 and self.arrowDirection<=per/2 then
s=s-360
goto check
elseif e<=per/2 and self.arrowDirection>=360-per/2 then
e=e+360
goto check
end
end
end
assert(false,"Damn it, I thought this was working perfectly!")
end
function Wheel:spin(x)self.landedOn=nil;self.extraRotate=x or 100 end
--Modified from something I found on the forums
Arc = class()
function Arc:init(x, y, r, s, e, c)
if not self.mesh then
self.mesh=mesh()
self.points = {}
self.points[1] = vec2(0, 0)
for i = s, e, 3 do
i = i / 180 * math.pi
table.insert(self.points, 1, vec2(math.cos(i), math.sin(i)))
end
self.mesh.vertices = triangulate(self.points)
end
self.x=x or 0
self.y=y or 0
self.r=r or 0
self.col=c or color(0,0,0,0)
end
function Arc:draw()
pushMatrix()
pushStyle()
translate(self.x, self.y)
scale(self.r)
fill(self.col)
self.mesh:draw()
popStyle()
popMatrix()
end
Hope you guys like it!