Add weapon charge UI.

This commit is contained in:
Anna Rose 2023-09-30 03:15:36 -04:00
parent a5bb3744b5
commit 032cc0a2ed
3 changed files with 89 additions and 11 deletions

View File

@ -8,6 +8,9 @@ import "ui"
local gfx <const> = playdate.graphics local gfx <const> = playdate.graphics
local BASE_CHARGE_FACTOR <const> = 15
local BASE_WEAPON_CHARGE_SPEED <const> = 1000
-- the amount of charge needed to increase the shot power by 1 at each power level -- the amount of charge needed to increase the shot power by 1 at each power level
local WEAPON_CHARGE_LOOKUP <const> = { local WEAPON_CHARGE_LOOKUP <const> = {
[0]=5, [0]=5,
@ -16,9 +19,6 @@ local WEAPON_CHARGE_LOOKUP <const> = {
[3]=50 [3]=50
} }
-- maximum value the reserve charge can reach
local MAX_CHARGE <const> = 100
class("Kani").extends(gfx.sprite) class("Kani").extends(gfx.sprite)
function Kani:init(ui) function Kani:init(ui)
@ -30,14 +30,22 @@ function Kani:init(ui)
self:setGroupMask(0x2) self:setGroupMask(0x2)
self:setCollidesWithGroupsMask(0x19) self:setCollidesWithGroupsMask(0x19)
-- stats
self.health = 100
self.reserveCharge = 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.weaponPower = 0
self.firingMode = false 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. -- the UI gets passed in to Kani so that we can update pieces of it easily.
self.ui = ui self.ui = ui
-- input handlers
self.inputHandlers = { self.inputHandlers = {
upButtonDown = function() self.vector.y = -3 end, upButtonDown = function() self.vector.y = -3 end,
downButtonDown = 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, rightButtonUp = function() self.vector.x = 0 end,
cranked = function(change, accelChange) self:chargeReserve(change) end, cranked = function(change, accelChange) self:chargeReserve(change) end,
AButtonDown = function() 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, end,
AButtonUp = function() self:fire() end, AButtonUp = function() self:fire() end,
} }
@ -57,7 +67,7 @@ end
function Kani:chargeReserve(change) function Kani:chargeReserve(change)
if change <= 0 then return end 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) self.ui.chargeMeter:setValue(self.reserveCharge)
end end
@ -76,8 +86,8 @@ function Kani:chargeShot()
if effectiveCharge >= requiredPower then if effectiveCharge >= requiredPower then
self.reserveCharge = effectiveCharge - requiredPower self.reserveCharge = effectiveCharge - requiredPower
self.weaponPower += 1 self.weaponPower += 1
print("Shot charged to size " .. self.weaponPower)
self.ui.chargeMeter:setValue(self.reserveCharge) self.ui.chargeMeter:setValue(self.reserveCharge)
self.ui.weaponPowerMeter:setValue(self.weaponPower-1)
end end
end end
@ -88,11 +98,20 @@ function Kani:fire()
return return
end end
print("Firing bullet of size " .. self.weaponPower)
local bullet = Bullet(self.weaponPower) local bullet = Bullet(self.weaponPower)
bullet:moveTo(self.x+16, self.y) bullet:moveTo(self.x+16, self.y)
bullet:add() bullet:add()
self.weaponPower = 0 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 end
function Kani:addInputHandlers() function Kani:addInputHandlers()
@ -107,6 +126,6 @@ end
function Kani:update() function Kani:update()
local collisions = select(3, self:moveWithCollisions(self.x + self.vector.x, self.y + self.vector.y)) local collisions = select(3, self:moveWithCollisions(self.x + self.vector.x, self.y + self.vector.y))
for i=0, #collisions, 1 do for i=0, #collisions, 1 do
-- handle collisions -- handle player-triggered collisions
end end
end end

57
src/pipmeter.lua Normal file
View File

@ -0,0 +1,57 @@
import "CoreLibs/graphics"
import "CoreLibs/object"
local gfx <const> = 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

View File

@ -2,24 +2,26 @@
-- we'll keep the OO semantics. -- we'll keep the OO semantics.
import "CoreLibs/object" import "CoreLibs/object"
import "meter" import "meter"
-- import "weaponpowerwidget" import "pipmeter"
class("UI", {}).extends(playdate.object) class("UI", {}).extends(playdate.object)
function UI:init() function UI:init()
self.chargeMeter = Meter(100, 10, 60) self.chargeMeter = Meter(100, 10, 60)
self.healthMeter = Meter(100, 60, 10, false) self.healthMeter = Meter(100, 60, 10, false)
-- self.weaponPowerWidget = WeaponPowerWidget() self.weaponPowerMeter = PipMeter(0, 4, 5, 3, 3)
self:moveTo(359, 199) self:moveTo(359, 199)
end end
function UI:add() function UI:add()
self.chargeMeter:add() self.chargeMeter:add()
self.healthMeter:add() self.healthMeter:add()
self.weaponPowerMeter:add()
end end
function UI:moveTo(x, y) function UI:moveTo(x, y)
-- figure out correct offsets later -- figure out correct offsets later
self.chargeMeter:moveTo(x + 35, y) self.chargeMeter:moveTo(x + 35, y)
self.healthMeter:moveTo(x, y + 35) self.healthMeter:moveTo(x, y + 35)
self.weaponPowerMeter:moveTo(x, y+20)
end end