From 032cc0a2ed93443cc462848bc7f34bd1f2863931 Mon Sep 17 00:00:00 2001 From: annabunches Date: Sat, 30 Sep 2023 03:15:36 -0400 Subject: [PATCH] Add weapon charge UI. --- src/kani.lua | 37 +++++++++++++++++++++++-------- src/pipmeter.lua | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ui.lua | 6 +++-- 3 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/pipmeter.lua diff --git a/src/kani.lua b/src/kani.lua index 8c1198f..21c18e2 100644 --- a/src/kani.lua +++ b/src/kani.lua @@ -8,6 +8,9 @@ import "ui" local gfx = playdate.graphics +local BASE_CHARGE_FACTOR = 15 +local BASE_WEAPON_CHARGE_SPEED = 1000 + -- the amount of charge needed to increase the shot power by 1 at each power level local WEAPON_CHARGE_LOOKUP = { [0]=5, @@ -16,9 +19,6 @@ local WEAPON_CHARGE_LOOKUP = { [3]=50 } --- maximum value the reserve charge can reach -local MAX_CHARGE = 100 - class("Kani").extends(gfx.sprite) function Kani:init(ui) @@ -30,14 +30,22 @@ function Kani:init(ui) self:setGroupMask(0x2) self:setCollidesWithGroupsMask(0x19) + -- stats + self.health = 100 self.reserveCharge = 100 + + -- controls the speed the crank recharges the player's reserves. A lower number allows faster charging. + -- should never be set to 0 + self.chargeFactor = BASE_CHARGE_FACTOR + + -- weapon variables self.weaponPower = 0 self.firingMode = false + self.weaponChargeSpeed = BASE_WEAPON_CHARGE_SPEED -- speed in ms between weapon charge levels. Level 2 always takes half this time. -- the UI gets passed in to Kani so that we can update pieces of it easily. self.ui = ui - -- input handlers self.inputHandlers = { upButtonDown = function() self.vector.y = -3 end, downButtonDown = function() self.vector.y = 3 end, @@ -49,7 +57,9 @@ function Kani:init(ui) rightButtonUp = function() self.vector.x = 0 end, cranked = function(change, accelChange) self:chargeReserve(change) end, AButtonDown = function() - self.firingTimer = playdate.timer.keyRepeatTimerWithDelay(500, 1000, self.chargeShot, self) + self.firingTimer = playdate.timer.keyRepeatTimerWithDelay(self.weaponChargeSpeed / 2, + self.weaponChargeSpeed, + self.chargeShot, self) end, AButtonUp = function() self:fire() end, } @@ -57,7 +67,7 @@ end function Kani:chargeReserve(change) if change <= 0 then return end - self.reserveCharge = math.min(self.reserveCharge + change / 15, 100) + self.reserveCharge = math.min(self.reserveCharge + change / self.chargeFactor, 100) self.ui.chargeMeter:setValue(self.reserveCharge) end @@ -76,8 +86,8 @@ function Kani:chargeShot() if effectiveCharge >= requiredPower then self.reserveCharge = effectiveCharge - requiredPower self.weaponPower += 1 - print("Shot charged to size " .. self.weaponPower) self.ui.chargeMeter:setValue(self.reserveCharge) + self.ui.weaponPowerMeter:setValue(self.weaponPower-1) end end @@ -88,11 +98,20 @@ function Kani:fire() return end - print("Firing bullet of size " .. self.weaponPower) local bullet = Bullet(self.weaponPower) bullet:moveTo(self.x+16, self.y) bullet:add() self.weaponPower = 0 + self.ui.weaponPowerMeter:setValue(0) +end + +function Kani:damage(amount) + self.health = math.max(self.health - amount, 0) + + if self.health <= 0 then + -- TODO: destroy ship + end + self.ui.healthMeter:setValue(self.health) end function Kani:addInputHandlers() @@ -107,6 +126,6 @@ end function Kani:update() local collisions = select(3, self:moveWithCollisions(self.x + self.vector.x, self.y + self.vector.y)) for i=0, #collisions, 1 do - -- handle collisions + -- handle player-triggered collisions end end diff --git a/src/pipmeter.lua b/src/pipmeter.lua new file mode 100644 index 0000000..d4c2eff --- /dev/null +++ b/src/pipmeter.lua @@ -0,0 +1,57 @@ +import "CoreLibs/graphics" +import "CoreLibs/object" + +local gfx = playdate.graphics + +class("PipMeter").extends(gfx.sprite) + +function PipMeter:init(initialValue, numPips, baseSize, sizeIncrement, spacing, circle) + PipMeter.super.init(self) + + self.numPips = numPips + self.baseSize = baseSize + self.sizeIncrement = sizeIncrement or 1 + self.spacing = spacing or 1 + self:setZIndex(999) + + -- using arithmetic progression: sum = (n * (firstValue + lastValue)) / 2 + -- (plus spacing) + local padBaseSize = baseSize + spacing + local lastSize = padBaseSize + (numPips - 1) * sizeIncrement + local width = (numPips * (padBaseSize + lastSize)) / 2 - spacing + self:setSize(width, lastSize) + + if self.circle then + self.drawFunc = gfx.drawCircleInRect + self.fillFunc = gfx.fillCircleInRect + else + self.drawFunc = gfx.drawRect + self.fillFunc = gfx.fillRect + end + + self:setValue(initialValue) +end + +function PipMeter:setValue(value) + local img = gfx.image.new(self:getSize()) + gfx.pushContext(img) + local offset = 0 + for i=1, self.numPips, 1 do + local size = self.baseSize+(self.sizeIncrement*(i-1)) + + print(string.format("Drawing a pip with %d %d %d %d", offset, self.height, size, size)) + + if value >= i then + self.fillFunc(offset, self.height - size, size, size) + else + self.drawFunc(offset, self.height - size, size, size) + gfx.setColor(gfx.kColorWhite) + self.fillFunc(offset+1, self.height - size +1, size-2, size-2) + gfx.setColor(gfx.kColorBlack) + end + + offset += size + self.spacing + end + gfx.popContext() + self:setImage(img) +end diff --git a/src/ui.lua b/src/ui.lua index 073a636..338b2bb 100644 --- a/src/ui.lua +++ b/src/ui.lua @@ -2,24 +2,26 @@ -- we'll keep the OO semantics. import "CoreLibs/object" import "meter" --- import "weaponpowerwidget" +import "pipmeter" class("UI", {}).extends(playdate.object) function UI:init() self.chargeMeter = Meter(100, 10, 60) self.healthMeter = Meter(100, 60, 10, false) - -- self.weaponPowerWidget = WeaponPowerWidget() + self.weaponPowerMeter = PipMeter(0, 4, 5, 3, 3) self:moveTo(359, 199) end function UI:add() self.chargeMeter:add() self.healthMeter:add() + self.weaponPowerMeter:add() end function UI:moveTo(x, y) -- figure out correct offsets later self.chargeMeter:moveTo(x + 35, y) self.healthMeter:moveTo(x, y + 35) + self.weaponPowerMeter:moveTo(x, y+20) end