Skip to content

Instantly share code, notes, and snippets.

@reefwing
Created July 30, 2012 11:05
Show Gist options
  • Save reefwing/3206212 to your computer and use it in GitHub Desktop.
Save reefwing/3206212 to your computer and use it in GitHub Desktop.
Tutorial 10 - A Simple Dial Class
--# Dial
Dial = class()
-- A Dial Class
-- Reefwing Software (www.reefwing.com.au)
--
-- 26 July 2012
-- Version 1.0
function Dial:init(x, y, angle)
-- These parameters are used to customise your Dial
self.x = x -- x screen co-ordinate for the dial
self.y = y -- y screen co-ordinate for the dial
self.alignment = CENTER -- Dial uses CENTER alignment
self.visible = true -- Boolean to indicate whether dial is drawn and touches handled
self.currentAngle = angle or 0 -- Current Angle of the dial in degrees (default 0)
dialImage = readImage("Dropbox:pDial200px")
knobImage = readImage("Dropbox:pKnob147px")
radius = knobImage.width/2 -- Radius of knob circle sprite
self.width = dialImage.width -- Defined by the dial sprite width
self.height = dialImage.height -- Defined by the dial sprite height
end
-- Draw function
function Dial:draw()
-- Codea does not automatically call this method
if self.visible then
sprite(dialImage, self.x, self.y)
pushMatrix()
rotateDialByDegrees(self.x, self.y, self.currentAngle)
sprite(knobImage, 0, 0)
popMatrix()
end
end
-- Touch Handler
function Dial:touched(touch)
-- Codea does not automatically call this method
--
-- The pointInCircle() function determines if the touch was
-- on the dial. This function is contained in RSLibrary.
--
-- math.polar(x, y) converts from cartesian co-ordinates (x, y) to polar
-- co-ordinates (distance, angle). We only use the returned angle not the
-- distance. This function is also contained in RSLibrary.
if self.visible and pointInCircle(touch.x, touch.y, self.x, self.y, radius) then
if touch.state == MOVING then
_, self.currentAngle = math.polar(touch.x, touch.y, self.x, self.y)
end
end
end
-- Utility Functions
function Dial:reset()
self.currentAngle = 0
end
function rotateDialByDegrees(centreX, centreY, angle)
translate(centreX, centreY)
rotate(angle)
end
--# Main
-- DialDemo
-- Define supported orientations
supportedOrientations(ANY)
-- Use this function to perform your initial setup
function setup()
-- Project Metadata
version = 1.0
saveProjectInfo("Description", "Codea Dial Demonstration")
saveProjectInfo("Author", "Reefwing Software")
saveProjectInfo("Date", "26th July 2012")
saveProjectInfo("Version", version)
print("DialDemo v"..version.."\n")
-- Keep an eye on Frame Rate (Frames Per Second, FPS) so we can
-- compare and contrast different approaches.
FPS = 0
watch("FPS")
-- Define a new dial = Dial(x, y, angle)
--
-- Where: (x, y) are the CENTER co-ordinates of the dial. (default alignment is CENTER).
-- angle = the current angle (in degrees) of the dial.
dial = Dial(WIDTH/2, HEIGHT/2, 0)
-- Create a button which will zero the dial
-- The Button Class is contained within RSLibrary
local rbX = WIDTH/2 - dial.width/2
local rbY = HEIGHT/2 - dial.height - 20
resetButton = Button("Reset", rbX, rbY, dial.width, 50)
resetButton.action = function() resetButtonTapped() end
end
-- Drawing Functions
function draw()
-- Update instantaneous FPS
FPS = math.round(1/DeltaTime)
-- This sets a black background color
background(blackColor)
-- Draw the dial and reset button
dial:draw()
resetButton:draw()
end
function orientationChanged(newOrientation)
-- If the iPad orientation changes we need to
-- adjust object co-ordinates.
local rbX = WIDTH/2 - dial.width/2
local rbY = HEIGHT/2 - dial.height - 20
dial.x, dial.y = WIDTH/2, HEIGHT/2
resetButton.x, resetButton.y = rbX, rbY
end
-- Handle Touches
function touched(touch)
dial:touched(touch)
resetButton:touched(touch)
end
function resetButtonTapped()
dial:reset()
end
function math.polar(x, y, originX, originY)
-- Usage: math.polar(x, y) - origin is assumed at (0, 0)
-- math.polar(x, y, originX, originY)
--
-- This function converts from cartesian co-ordinates (x, y) to
-- polar co-ordinates (distance, angle) using the two functions:
--
-- 1. distance = hypot(x, y) - the hypotenuse of a right-angle triangle; and
-- 2. angle = atan2(x, y) - is the arc tangent of y/x in radians.
--
-- Since nil evaluates to false in Lua, you can use "or" to assign a default value.
--
-- Reefwing Software (www.reefwing.com.au)
-- Version 1.0
local oX = originX or 0
local oY = originY or 0
local dx = x - oX
local dy = y - oY
local distance = math.hypot(dx, dy)
local angleInDegrees = math.deg(math.atan2(dy, dx))
-- Functions may return multiple results in Lua.
return distance, angleInDegrees
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment