local Button = Object:extend() local ButtonCircle = Object:extend() local TweenManager = require "birb.classes.time" local keys = {"A", "B", "C", "select", "up", "down", "left", "right"} local BTN_SIZE = 21 local CANVAS_SIZE = 21+2 local SHAKETIME = 0.02 local SHAKEPOWER = 4 local function myStencilFunction() love.graphics.circle("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2 - 1) end function Button:new(prompt, key, number, beginTime) self.prompt = prompt self.key = key self.number = number or 1 self.showNumber = (self.number > 1) self.isPressed = false self.lum = 1 self.opacity = 0 self.frame = self:getFrame() self.scale = 1.25 self.isFailed = false self.shakeTimer = SHAKETIME self.shakex, self.shakey = 0, 0 self.circles = {} self.timerTexture = nil self.tweens = TweenManager(self) self.tweens:newTween(0, beginTime, {opacity = 1, scale = 1}, "inOutQuart") end function Button:getFrame() for i, key in ipairs(keys) do if (key == self.key) then return i end end error("Non existing key " .. self.key) end function Button:update(dt, isFirst) self.tweens:update(dt) for i, circle in ipairs(self.circles) do circle:update(dt) end if (self.isFailed) then self.shakeTimer = self.shakeTimer - dt if (self.shakeTimer < 0) then self.shakeTimer = SHAKETIME self.shakex = math.random(SHAKEPOWER*2) - (SHAKEPOWER) self.shakey = math.random(SHAKEPOWER*2) - (SHAKEPOWER) end end if (isFirst) then self.timerTexture = love.graphics.newCanvas(CANVAS_SIZE, CANVAS_SIZE) love.graphics.setCanvas({self.timerTexture, stencil = true}) love.graphics.setColor(0.5, 0.5, 0.5, 1) love.graphics.circle("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2) utils.graphics.setColorHSV(self.prompt:getTimer()/3, 1, 1) love.graphics.stencil(myStencilFunction, "replace", 1) love.graphics.setStencilTest("greater", 0) love.graphics.arc("fill", CANVAS_SIZE/2, CANVAS_SIZE/2, BTN_SIZE/2, 0 - (math.pi/2), ((math.pi*2*self.prompt:getTimer()) - (math.pi/2)), 16) love.graphics.setStencilTest() love.graphics.setCanvas() end end function Button:verifyPrompts(sourceKeys, removeWhenPressed) local mustBeRemoved = false local keyValue = 0 self.lum = 1 for i, key in ipairs(keys) do if (sourceKeys[key].isPressed) then if (key == self.key) then keyValue = 1 self.lum = 0.8 table.insert(self.circles, ButtonCircle()) else keyValue = -1 self.isFailed = true end end end if (removeWhenPressed and keyValue == 1) then self.number = self.number - 1 if (self.number == 0) then mustBeRemoved = true end end return keyValue, mustBeRemoved end function Button:finish(success) local scale = 0.75 if (success == true) then scale = 1.25 end self.tweens:newTween(0, 0.15, {opacity = 0, scale = scale}, "inOutQuart") end function Button:draw(x, y, isFirst) local x, y = x + self.shakex, y + self.shakey love.graphics.setColor(1,1,1,self.circleOpacity) for i, circle in ipairs(self.circles) do circle:draw(x, y) end love.graphics.setColor(self.lum,self.lum,self.lum,self.opacity) if (isFirst and self.timerTexture ~= nil) then love.graphics.draw(self.timerTexture, x, y, 0, -self.scale, self.scale, 12, 11) end self.prompt.assets.tileset["qtebtn"]:drawTile(self.frame, x, y, 0, self.scale, self.scale, 8, 8) love.graphics.setColor(1,1,1,1) if (self.number > 0 and self.showNumber) then self.prompt.assets.fonts["hudnbrs_small"]:draw(utils.math.numberToString(self.number, 2), x, y + 2, -1, "left") end end function ButtonCircle:new() self.radius = 6 self.opacity = 1 self.tweens = TweenManager(self) self.tweens:newTween(0, 0.2, {radius = 12}, "inOutQuart") self.tweens:newTween(0.1, 0.1, {opacity = 0}, "inOutQuart") end function ButtonCircle:update(dt) self.tweens:update(dt) end function ButtonCircle:draw(x, y) love.graphics.setColor(1,1,1,self.opacity) love.graphics.circle("line",x,y,self.radius, 16) end return Button