assemble minigame
BIN
source/assets/sprites/assemble/1/1.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
source/assets/sprites/assemble/1/2.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
source/assets/sprites/assemble/1/3.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
source/assets/sprites/assemble/1/4.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
source/assets/sprites/assemble/1/5.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
source/assets/sprites/assemble/1/6.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
source/assets/sprites/assemble/1/7.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
source/assets/sprites/assemble/1/8.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
source/assets/sprites/assemble/sd.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
source/assets/sprites/buttons/A.png
Normal file
After Width: | Height: | Size: 628 B |
BIN
source/assets/sprites/buttons/B.png
Normal file
After Width: | Height: | Size: 210 B |
BIN
source/assets/sprites/buttons/DOWN.png
Normal file
After Width: | Height: | Size: 203 B |
BIN
source/assets/sprites/buttons/LEFT.png
Normal file
After Width: | Height: | Size: 200 B |
BIN
source/assets/sprites/buttons/RIGHT.png
Normal file
After Width: | Height: | Size: 200 B |
BIN
source/assets/sprites/buttons/UP.png
Normal file
After Width: | Height: | Size: 205 B |
@ -39,10 +39,12 @@ import "scripts/groundSprite"
|
||||
import "scripts/balebaSprite"
|
||||
import "scripts/dangerSprite"
|
||||
import "scripts/tankSprite"
|
||||
import "scripts/progressBar"
|
||||
|
||||
import "scenes/BaseScene"
|
||||
import 'scenes/Menu'
|
||||
import 'scenes/Game'
|
||||
import 'scenes/Assemble'
|
||||
|
||||
Noble.Settings.setup({
|
||||
difficulty = "Medium",
|
||||
@ -57,4 +59,4 @@ playdate.display.setRefreshRate(50)
|
||||
|
||||
Noble.showFPS = true
|
||||
|
||||
Noble.new(Game)
|
||||
Noble.new(Assemble)
|
||||
|
187
source/scenes/Assemble.lua
Normal file
@ -0,0 +1,187 @@
|
||||
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
|
28
source/scripts/progressBar.lua
Normal file
@ -0,0 +1,28 @@
|
||||
local pd <const> = playdate
|
||||
local gfx <const> = Graphics
|
||||
|
||||
class('ProgressBar').extends(gfx.sprite)
|
||||
|
||||
function ProgressBar:init(x, y, width, height)
|
||||
self:setImage(gfx.image.new(width, height))
|
||||
self.progress = 0
|
||||
self:moveTo(x, y)
|
||||
self:add()
|
||||
self:set(0)
|
||||
end
|
||||
|
||||
function ProgressBar:set(percentage)
|
||||
self.progress = percentage
|
||||
local bar_image = gfx.image.new(self.width, self.height, gfx.kColorWhite)
|
||||
local progressWidth = self.progress / 100 * (self.width - 4)
|
||||
-- local _, fontHeight = playdate.graphics.getTextSize("TEST")
|
||||
gfx.pushContext(bar_image)
|
||||
gfx.setLineWidth(2)
|
||||
gfx.drawRoundRect(1, 1, self.width - 2, self.height - 2, 3)
|
||||
gfx.fillRect(2, 2, progressWidth, self.height - 4)
|
||||
gfx.setImageDrawMode(gfx.kDrawModeNXOR)
|
||||
--[[ gfx.drawTextAligned(math.floor(self.progress) .. "%", self.width / 2, (self.height - fontHeight) / 2 + 2,
|
||||
kTextAlignment.center) ]]
|
||||
gfx.popContext()
|
||||
self:setImage(bar_image)
|
||||
end
|