Assemble = {} class("Assemble").extends(BaseScene) local scene = Assemble local font = Graphics.font.new('assets/fonts/Mini Sans 2X') local allButtons = { "A", "B", "DOWN", "LEFT", "RIGHT", "UP" } local function screenShake(shakeTime, shakeMagnitude) local shakeTimer = playdate.timer.new(shakeTime, shakeMagnitude, 0) shakeTimer.updateCallback = function(timer) local magnitude = math.floor(timer.value) local shakeX = math.random(-magnitude, magnitude) local shakeY = math.random(-magnitude, magnitude) playdate.display.setOffset(shakeX, shakeY) end shakeTimer.timerEndedCallback = function() playdate.display.setOffset(0, 0) end end function scene:popCode(button) if scene.tickTimer.paused then scene.droneParts = scene:loadDrone(1, #scene.code) scene.tickTimer:start() scene.progressBar:setVisible(true) end if button == scene.code[1] then table.remove(scene.code, 1) scene.tickTimer:reset() scene.dronePartIndex = scene.dronePartIndex + 1 local particle = ParticlePoly(200, 190 + 8) particle:setThickness(2) particle:setSize(1, 2) particle:setSpeed(1, 3) particle:setColour(Graphics.kColorXOR) particle:add(5) else self.buttonTimeout = self.buttonTimeout - 5 scene.code[1] = scene:randomButton() screenShake(100, 5) end end scene.inputHandler = { AButtonDown = function() scene:popCode("A") end, BButtonDown = function() scene:popCode("B") end, downButtonDown = function() scene:popCode("DOWN") end, leftButtonDown = function() scene:popCode("LEFT") end, rightButtonDown = function() scene:popCode("RIGHT") end, upButtonDown = function() scene:popCode("UP") end, } function scene:randomButton() local button = allButtons[math.random(1, #allButtons)] return button end function scene:drawBackground() end local screwDriver = Graphics.image.new('assets/sprites/assemble/sd.png') function scene:loadButtons() local buttons = {} for i = 1, #allButtons do local image = Graphics.image.new('assets/sprites/buttons/' .. allButtons[i] .. '.png') buttons[allButtons[i]] = image end return buttons end function scene:loadDrone(id, parts) local drone = {} for i = 1, parts do local image = Graphics.image.new('assets/sprites/assemble/' .. id .. '/' .. i .. '.png') if image ~= nil then table.insert(drone, image) end end return drone end function scene:setValues() scene.code = {} for i = 1, 9 do table.insert(scene.code, scene:randomButton()) end scene.buttons = scene:loadButtons() scene.droneParts = {} scene.dronePartIndex = 0 end function scene:init() scene.super.init(self) scene:setValues() scene.buttonTimeout = 100 scene.progressBar = ProgressBar(200, 170, 50, 5) scene.progressBar:set(self.buttonTimeout) scene.progressBar:setVisible(false) scene.tickTimer = playdate.timer.new(2500, self.buttonTimeout, 0, playdate.easingFunctions.linear) scene.tickTimer.updateCallback = function(timer) scene.buttonTimeout = timer.value scene.progressBar:set(scene.buttonTimeout) end scene.tickTimer.timerEndedCallback = function() scene.buttonTimeout = 0 end scene.tickTimer:pause() end function scene:start() scene.super.start(self) self.optionsMenu:addMenuItem("Main Menu", function() Noble.transition(Menu) end) Noble.showFPS = true end function scene:enter() scene.super.enter(self) end function round(number) local formatted = string.format("%.2f", number) return formatted end function scene:update() scene.super.update(self) if #scene.code == 0 then Noble.Text.draw("WIN!", 200, 110, Noble.Text.ALIGN_CENTER, false, font) self.progressBar:remove() self.tickTimer:remove() scene.inputHandler = {} return end if scene.buttonTimeout <= 0 then Noble.Text.draw("LOSE!", 200, 110, Noble.Text.ALIGN_CENTER, false, font) self.progressBar:remove() self.tickTimer:remove() screenShake(100, 5) scene.inputHandler = {} return end screwDriver:draw(300, 100) if scene.droneParts ~= nil and scene.dronePartIndex ~= nil and scene.dronePartIndex > 0 and #scene.droneParts > 0 then scene.droneParts[scene.dronePartIndex]:draw(100, 20) end Graphics.drawLine(200, 175, 200, 185) Graphics.drawLine(200, 212, 200, 222) for i = 1, #scene.code do local button = scene.buttons[scene.code[i]] local first = 1 if #scene.code == 1 then first = 0 end local t = (i - 1) / (#scene.code - first) local opaque = playdate.math.lerp(1, 0.3, t) --TODO: not the best solution button:drawFaded(200 + ((i - 1) * 16) - 8, 190, opaque, playdate.graphics.image.kDitherTypeBayer2x2) end end function scene:exit() scene.super.exit(self) Noble.showFPS = false end function scene:finish() scene.super.finish(self) playdate.display.setScale(1) end