From d50fefa68f314cae4e78afca6bb70bbf1dbe4b63 Mon Sep 17 00:00:00 2001 From: Brandon Dyck Date: Tue, 26 Mar 2024 21:57:50 -0600 Subject: [PATCH] Make Clock class with draggable hand --- clock.lua | 122 ++++++++++++++++++++++++++++++++++++++++++------ main.lua | 135 +++++++++++++++++++++++++++++------------------------- 2 files changed, 179 insertions(+), 78 deletions(-) diff --git a/clock.lua b/clock.lua index 35ac334..64cb895 100644 --- a/clock.lua +++ b/clock.lua @@ -1,35 +1,127 @@ local MAX_SECONDS = 60 * 60 * 12 +local Time = {} +Time.__index = Time + +function Time:new(hour, minute) + local t = { + hour = (hour or 12), + minute = (minute or 0) + } + return setmetatable(t, self) +end + +function Time:getHour() + return self.hour +end + +function Time:getMinute() + return self.minute +end + +function Time:fmt() + return string.format("%2d:%02d", self.hour, self.minute) +end + + local Hand = {} Hand.__index = Hand -function Hand:new(length, color, sec_per_turn, ticks_per_turn) +function Hand:new(length, color) local h = { length = (length or 10), color = (color or {1,1,1}), - sec_per_turn = (sec_per_turn or 1), - ticks_per_turn = ticks_per_turn + turns = 0 } return setmetatable(h, self) end -local function handTransform(sec_elapsed) - local turns = sec_elapsed / self.sec_per_turn - if self.ticks_per_turn then - turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn - end - return love.math.newTransform(0, 0, 2 * math.pi * turns) +function Hand:setTurns(turns) + self.turns = turns end -function Hand:draw(sec_elapsed) - local turns = sec_elapsed / self.sec_per_turn - if self.ticks_per_turn then - turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn - end +function Hand:getTurns() + return self.turns +end + +function Hand:draw() +-- local turns = sec_elapsed / self.sec_per_turn +-- if self.ticks_per_turn then +-- turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn +-- end love.graphics.push("all") - love.graphics.applyTransform(handTransform(sec_elapsed)) love.graphics.setColor(unpack(self.color)) + love.graphics.rotate(2 * math.pi * (self.turns + 0.25)) love.graphics.rectangle("fill", -10, 10, 20, -self.length) love.graphics.pop() end + +local Clock = {} +Clock.__index = Clock + +function Clock:new(time, diameter, transform) + local c = { + time = (time or Time:new()), + minuteHand = Hand:new(240, {1,0,0}, 60*60), + dragging = false, + transform = transform or love.math.newTransform(), + radius = diameter and diameter/2 or 300 + } + return setmetatable(c, self) +end + +function Clock:setTime(time) + self.time = time +end + +function Clock:getTime() + return self.time +end + +function Clock:draw() + -- debug + love.graphics.print(self.minuteHand:getTurns(), 10, 50) + -- end debug + + love.graphics.push("all") + love.graphics.applyTransform(self.transform) + love.graphics.setColor(0.5, 0.5, 0.5) + love.graphics.circle("fill", 0, 0, self.radius) + self.minuteHand:draw() + love.graphics.pop() +end + +local function clockContainsPoint(clock, x, y) + local localX, localY = clock.transform:inverseTransformPoint(x, y) + local dist = math.sqrt(localX^2 + localY^2) + return dist <= clock.radius +end + +local function clockPointAt(clock, x, y) + local localX, localY = clock.transform:inverseTransformPoint(x, y) + local turns = math.atan2(localY, localX) / 2 / math.pi + clock.minuteHand:setTurns(turns) +end + +function Clock:movemouse(x, y) + if self.dragging then + local localX, localY = self.transform:inverseTransformPoint(x, y) + clockPointAt(self, x, y) + -- TODO update clock hands + end +end + +function Clock:pressmouse(x, y, button) + if not self.dragging and button == 1 and clockContainsPoint(self, x,y) then + self.dragging = true + clockPointAt(self, x, y) + -- TODO update clock hands + end +end + +function Clock:releasemouse(button) + if button == 1 then self.dragging = false end +end + +return Clock \ No newline at end of file diff --git a/main.lua b/main.lua index de10df9..524e155 100644 --- a/main.lua +++ b/main.lua @@ -1,77 +1,86 @@ -local MAX_SECONDS = 60 * 60 * 12 +--local MAX_SECONDS = 60 * 60 * 12 -local Hand = {} -Hand.__index = Hand +--local Hand = {} +--Hand.__index = Hand -function Hand:new(length, color, sec_per_turn, ticks_per_turn) - local h = { - length = (length or 10), - color = (color or {1,1,1}), - sec_per_turn = (sec_per_turn or 1), - ticks_per_turn = ticks_per_turn - } - return setmetatable(h, self) +--function Hand:new(length, color, sec_per_turn, ticks_per_turn) +-- local h = { +-- length = (length or 10), +-- color = (color or {1,1,1}), +-- sec_per_turn = (sec_per_turn or 1), +-- ticks_per_turn = ticks_per_turn +-- } +-- return setmetatable(h, self) +--end + +--function Hand:draw(sec_elapsed) +-- local turns = sec_elapsed / self.sec_per_turn +-- if self.ticks_per_turn then +-- turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn +-- end +-- love.graphics.push("all") +-- love.graphics.setColor(unpack(self.color)) +-- love.graphics.rotate(2 * math.pi * turns) +-- love.graphics.rectangle("fill", -10, 10, 20, -self.length) +-- love.graphics.pop() +--end + +--local clock = {rawseconds = 0, speedup = 120} + +--function clock:advance(dt) +-- self.rawseconds = self.rawseconds + dt * self.speedup +-- if self.rawseconds >= MAX_SECONDS then +-- self.rawseconds = self.rawseconds - MAX_SECONDS +-- end +--end + +--function clock:getHour() +-- local h = math.floor(self.rawseconds / 60 / 60 % 12) +-- if h == 0 then +-- h = 12 +-- end +-- return h +--end + +--function clock:getMinute() +-- return math.floor(self.rawseconds / 60 % 60) +--end + +--function clock:getSecond() +-- return math.floor(self.rawseconds % 60) +--end + +--function clock:fmt() +-- return string.format("%2d:%02d:%02d", self:getHour(), self:getMinute(), self:getSecond()) +--end + +--local secondhand = Hand:new(300, {0.5,0.5,0}, 60, 60) +--local minutehand = Hand:new(240, {1,0,0}, 60*60) +--local hourhand = Hand:new(180, {0,0.5,0.5}, 60*60*12) + +-- New stuff: +local Clock = require"clock" +local clockTransform = love.math.newTransform(love.graphics.getWidth()/2, love.graphics.getHeight()/2) +local clock = Clock:new(nil, 400, clockTransform) + +function love.mousemoved(x, y, dx, dy, istouch) + clock:movemouse(x, y) end -function Hand:draw(sec_elapsed) - local turns = sec_elapsed / self.sec_per_turn - if self.ticks_per_turn then - turns = math.floor(turns * self.ticks_per_turn) / self.ticks_per_turn - end - love.graphics.push("all") - love.graphics.setColor(unpack(self.color)) - love.graphics.rotate(2 * math.pi * turns) - love.graphics.rectangle("fill", -10, 10, 20, -self.length) - love.graphics.pop() +-- todo mousepressed & mousereleased +function love.mousepressed(x, y, button, istouch, presses) + clock:pressmouse(x, y, button) end -local clock = {rawseconds = 0, speedup = 120} - -function clock:advance(dt) - self.rawseconds = self.rawseconds + dt * self.speedup - if self.rawseconds >= MAX_SECONDS then - self.rawseconds = self.rawseconds - MAX_SECONDS - end +function love.mousereleased(x, y, button, istouch, presses) + clock:releasemouse(button) end -function clock:getHour() - local h = math.floor(self.rawseconds / 60 / 60 % 12) - if h == 0 then - h = 12 - end - return h -end - -function clock:getMinute() - return math.floor(self.rawseconds / 60 % 60) -end - -function clock:getSecond() - return math.floor(self.rawseconds % 60) -end - -function clock:fmt() - return string.format("%2d:%02d:%02d", self:getHour(), self:getMinute(), self:getSecond()) -end - -local secondhand = Hand:new(300, {0.5,0.5,0}, 60, 60) -local minutehand = Hand:new(240, {1,0,0}, 60*60) -local hourhand = Hand:new(180, {0,0.5,0.5}, 60*60*12) - function love.load() love.graphics.setBackgroundColor(0,0,0) end -function love.update(dt) - clock:advance(dt) -end - function love.draw() - love.graphics.print(clock:fmt()) - love.graphics.print(math.floor(clock.rawseconds), 10, 50) - - love.graphics.translate(love.graphics.getWidth()/2, love.graphics.getHeight()/2) - secondhand:draw(clock.rawseconds) - minutehand:draw(clock.rawseconds) - hourhand:draw(clock.rawseconds) + love.graphics.print(clock:getTime():fmt()) + clock:draw() end