From 2e87bc88363f373310a5dd8338f26c38d6a3996f Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Thu, 6 Mar 2025 01:06:46 -0500 Subject: [PATCH] Almost-working upgrade menu. Basic input system. More advanced text-drawing system. --- src/assets.lua | 8 +- src/assets.lua2p | 6 +- .../Asheville-Sans-14-Bold-table-20-20.png | Bin 0 -> 10607 bytes src/assets/fonts/Asheville-Sans-14-Bold.fnt | 295 ++++++++++++++++++ src/main.lua | 16 +- src/systems/draw.lua | 44 ++- src/systems/filter-types.lua | 12 + src/systems/input.lua | 18 ++ src/systems/menu.lua | 26 ++ src/systems/move-toward.lua | 43 ++- src/systems/rounds.lua | 61 ++-- src/systems/spawner.lua | 7 +- src/systems/velocity.lua | 5 +- src/utils.lua | 2 +- 14 files changed, 477 insertions(+), 66 deletions(-) create mode 100755 src/assets/fonts/Asheville-Sans-14-Bold-table-20-20.png create mode 100755 src/assets/fonts/Asheville-Sans-14-Bold.fnt create mode 100644 src/systems/input.lua create mode 100644 src/systems/menu.lua diff --git a/src/assets.lua b/src/assets.lua index 972b732..11da147 100644 --- a/src/assets.lua +++ b/src/assets.lua @@ -28,6 +28,8 @@ TomatoSprite = playdate.graphics.image.new("assets/images/TomatoSprite.png") -- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer')) -- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer')) --- !!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value) --- return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft") --- end)) +-- luacheck: ignore +---@type pd_font +AshevilleSans14Bold = playdate.graphics.font.new("assets/fonts/Asheville-Sans-14-Bold.pft") + + diff --git a/src/assets.lua2p b/src/assets.lua2p index 99a0f6c..d200829 100644 --- a/src/assets.lua2p +++ b/src/assets.lua2p @@ -28,6 +28,6 @@ end)!!(generatedFileWarning()) !!(dirLookup('assets/images', 'png', 'playdate.graphics.image.new', 'pd_image')) -- !!(dirLookup('assets/sounds', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer')) -- !!(dirLookup('assets/music', 'wav', 'playdate.sound.sampleplayer.new', 'pd_sampleplayer')) --- !!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value) --- return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft") --- end)) +!!(dirLookup('assets/fonts', 'fnt', 'playdate.graphics.font.new', 'pd_font', nil, nil, function(varName, value) + return varName:gsub("[- ]", "") .. " = " .. value:gsub("fnt", "pft") +end)) diff --git a/src/assets/fonts/Asheville-Sans-14-Bold-table-20-20.png b/src/assets/fonts/Asheville-Sans-14-Bold-table-20-20.png new file mode 100755 index 0000000000000000000000000000000000000000..2b3c6a83e6c01c9f1e521a11f3a7a21e4e4afb4a GIT binary patch literal 10607 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 7 +? 9 +@ 11 +A 10 +B 9 +C 9 +D 9 +E 8 +F 8 +G 9 +H 9 +I 2 +J 8 +K 10 +L 9 +M 12 +N 9 +O 9 +P 9 +Q 9 +R 9 +S 9 +T 10 +U 9 +V 10 +W 14 +X 8 +Y 8 +Z 8 +[ 3 +\ 6 +] 3 +^ 6 +_ 8 +` 3 +a 8 +b 8 +c 8 +d 8 +e 8 +f 6 +g 8 +h 8 +i 2 +j 4 +k 8 +l 2 +m 12 +n 8 +o 8 +p 8 +q 8 +r 6 +s 8 +t 6 +u 8 +v 8 +w 12 +x 9 +y 8 +z 8 +{ 6 +| 2 +} 6 +~ 10 +… 8 +¥ 8 +‼ 5 +™ 8 +© 11 +® 11 +。 16 +、 16 +ぁ 16 +あ 16 +ぃ 16 +い 16 +ぅ 16 +う 16 +ぇ 16 +え 16 +ぉ 16 +お 16 +か 16 +が 16 +き 16 +ぎ 16 +く 16 +ぐ 16 +け 16 +げ 16 +こ 16 +ご 16 +さ 16 +ざ 16 +し 16 +じ 16 +す 16 +ず 16 +せ 16 +ぜ 16 +そ 16 +ぞ 16 +た 16 +だ 16 +ち 16 +ぢ 16 +っ 16 +つ 16 +づ 16 +て 16 +で 16 +と 16 +ど 16 +な 16 +に 16 +ぬ 16 +ね 16 +の 16 +は 16 +ば 16 +ぱ 16 +ひ 16 +び 16 +ぴ 16 +ふ 16 +ぶ 16 +ぷ 16 +へ 16 +べ 16 +ぺ 16 +ほ 16 +ぼ 16 +ぽ 16 +ま 16 +み 16 +む 16 +め 16 +も 16 +ゃ 16 +や 16 +ゅ 16 +ゆ 16 +ょ 16 +よ 16 +ら 16 +り 16 +る 16 +れ 16 +ろ 16 +ゎ 16 +わ 16 +ゐ 16 +ゑ 16 +を 16 +ん 16 +ゔ 16 +ゕ 16 +ゖ 16 +゛ 1 +゜ 0 +ゝ 16 +ゞ 16 +ゟ 16 +゠ 16 +ァ 16 +ア 16 +ィ 16 +イ 16 +ゥ 16 +ウ 16 +ェ 16 +エ 16 +ォ 16 +オ 16 +カ 16 +ガ 16 +キ 16 +ギ 16 +ク 16 +グ 16 +ケ 16 +ゲ 16 +コ 16 +ゴ 16 +サ 16 +ザ 16 +シ 16 +ジ 16 +ス 16 +ズ 16 +セ 16 +ゼ 16 +ソ 16 +ゾ 16 +タ 16 +ダ 16 +チ 16 +ヂ 16 +ッ 16 +ツ 16 +ヅ 16 +テ 16 +デ 16 +ト 16 +ド 16 +ナ 16 +ニ 16 +ヌ 16 +ネ 16 +ノ 16 +ハ 16 +バ 16 +パ 16 +ヒ 16 +ビ 16 +ピ 16 +フ 16 +ブ 16 +プ 16 +ヘ 16 +ベ 16 +ペ 16 +ホ 16 +ボ 16 +ポ 16 +マ 16 +ミ 16 +ム 16 +メ 16 +モ 16 +ャ 16 +ヤ 16 +ュ 16 +ユ 16 +ョ 16 +ヨ 16 +ラ 16 +リ 16 +ル 16 +レ 16 +ロ 16 +ヮ 16 +ワ 16 +ヰ 16 +ヱ 16 +ヲ 16 +ン 16 +ヴ 16 +ヵ 16 +ヶ 16 +ヷ 16 +ヸ 16 +ヹ 16 +ヺ 16 +・ 16 +ー 16 +ヽ 16 +ヾ 16 +ヿ 16 +「 16 +」 16 +円 16 +� 13 \ No newline at end of file diff --git a/src/main.lua b/src/main.lua index 529c20b..3b31cf4 100644 --- a/src/main.lua +++ b/src/main.lua @@ -15,15 +15,19 @@ world = tiny.world() import("tiny-tools.lua") import("assets.lua") import("systems/filter-types.lua") -import("systems/camera-pan.lua") -import("systems/collision-detection.lua") -import("systems/collision-resolution.lua") -import("systems/draw.lua") import("systems/gravity.lua") import("systems/move-toward.lua") +import("systems/velocity.lua") import("systems/rounds.lua") import("systems/spawner.lua") -import("systems/velocity.lua") +import("systems/camera-pan.lua") +import("systems/collision-resolution.lua") +import("systems/collision-detection.lua") + +import("systems/draw.lua") +import("systems/input.lua") +import("systems/menu.lua") + import("ingredients/ingredients.lua") import("cart.lua") import("utils.lua") @@ -79,7 +83,7 @@ function playdate.update() floor.position.x = Camera.pan.x - 600 - world:update(deltaSeconds) + world:update(math.min(1 / 40, deltaSeconds)) gfx.setDrawOffset(0, 0) Score:draw() diff --git a/src/systems/draw.lua b/src/systems/draw.lua index e683fdf..89c6020 100644 --- a/src/systems/draw.lua +++ b/src/systems/draw.lua @@ -4,10 +4,46 @@ drawRectanglesSystem = filteredSystem({ position = T.XyPair, drawAsRectangle = { gfx.fillRect(e.position.x, e.position.y, e.drawAsRectangle.size.x, e.drawAsRectangle.size.y) end) -drawTextSystem = filteredSystem({ position = T.XyPair, drawAsText = { text = T.str } }, function(e, dt) - gfx.drawTextAligned(e.drawAsText.text, e.position.x, e.position.y, gfx.kAlignCenter) -end) - drawSpriteSystem = filteredSystem({ position = T.XyPair, drawAsSprite = T.PdImage }, function(e, dt, system) e.drawAsSprite:draw(e.position.x, e.position.y) end) + +local textHeight = AshevilleSans14Bold:getHeight() +local xMargin = 4 + +drawTextSystem = filteredSystem( + { position = T.XyPair, drawAsText = { text = T.str, style = Maybe(T.str) } }, + function(e, dt) + local textWidth = AshevilleSans14Bold:getTextWidth(e.drawAsText.text) + if e.drawAsText.style == TextStyle.Inverted then + gfx.fillRect( + e.position.x - xMargin - textWidth / 2, + e.position.y - 2, + textWidth + (xMargin * 2), + textHeight + 2 + ) + gfx.setImageDrawMode(gfx.kDrawModeInverted) + end + if e.drawAsText.style == TextStyle.Bordered then + gfx.setColor(gfx.kColorWhite) + gfx.fillRect( + e.position.x - xMargin - textWidth / 2, + e.position.y - 2, + textWidth + (xMargin * 2), + textHeight + 2 + ) + gfx.setColor(gfx.kColorBlack) + gfx.setImageDrawMode(gfx.kDrawModeCopy) + gfx.drawRect( + e.position.x - xMargin - textWidth / 2, + e.position.y - 2, + textWidth + (xMargin * 2), + textHeight + 2 + ) + end + AshevilleSans14Bold:drawTextAligned(e.drawAsText.text, e.position.x, e.position.y, kTextAlignment.center) + if e.drawAsText.style == TextStyle.Inverted then + gfx.setImageDrawMode(gfx.kDrawModeCopy) + end + end +) diff --git a/src/systems/filter-types.lua b/src/systems/filter-types.lua index cadb85d..2667283 100644 --- a/src/systems/filter-types.lua +++ b/src/systems/filter-types.lua @@ -18,6 +18,8 @@ local XyPair = { x = 1, y = 1 } ---@alias CanSpawn { entity: Entity } +---@alias InRelations Entity[] + T = { XyPair = XyPair, bool = true, @@ -49,6 +51,10 @@ T = { RoundStateAction = "start", ---@type CanSpawn CanSpawn = {}, + ---@type InRelations + InRelations = {}, + ---@type InputState + InputState = {}, } ---@generic T @@ -57,3 +63,9 @@ T = { function Maybe(t) return { maybe = t } end + +TextStyle = { + Inverted = "INVERTED", + Bordered = "BORDERED", + None = "None", +} diff --git a/src/systems/input.lua b/src/systems/input.lua new file mode 100644 index 0000000..a226204 --- /dev/null +++ b/src/systems/input.lua @@ -0,0 +1,18 @@ +---@alias InputState { upJustPressed: boolean, downJustPressed: boolean, rightJustPressed: boolean, leftJustPressed: boolean, aJustPressed: boolean, bJustPressed: boolean } + +local buttonJustPressed = playdate.buttonJustPressed +local inputState = {} + +inputSystem = filteredSystem({ canReceiveInput = T.marker }, function(e, _, system) + e.inputState = inputState + system.world:addEntity(e) +end) + +function inputSystem:preProcess() + inputState.upJustPressed = buttonJustPressed(playdate.kButtonUp) + inputState.downJustPressed = buttonJustPressed(playdate.kButtonDown) + inputState.rightJustPressed = buttonJustPressed(playdate.kButtonRight) + inputState.leftJustPressed = buttonJustPressed(playdate.kButtonLeft) + inputState.aJustPressed = buttonJustPressed(playdate.kButtonA) + inputState.bJustPressed = buttonJustPressed(playdate.kButtonB) +end diff --git a/src/systems/menu.lua b/src/systems/menu.lua new file mode 100644 index 0000000..d226fc1 --- /dev/null +++ b/src/systems/menu.lua @@ -0,0 +1,26 @@ +menuController = filteredSystem({ menuItems = T.InRelations, inputState = T.InputState }, function(e, _, _) + for _, menuItem in pairs(e.menuItems) do + if menuItem.highlighted then + if e.inputState.aJustPressed then + menuItem.onSelect() + end + if e.inputState.downJustPressed and menuItem.navigateDown then + menuItem.highlighted = false + menuItem.navigateDown.highlighted = true + return + end + if e.inputState.upJustPressed and menuItem.navigateUp then + menuItem.highlighted = false + menuItem.navigateUp.highlighted = true + return + end + end + end + for _, menuItem in pairs(e.menuItems) do + if menuItem.highlighted then + menuItem.drawAsText.style = TextStyle.Inverted + else + menuItem.drawAsText.style = TextStyle.Bordered + end + end +end) diff --git a/src/systems/move-toward.lua b/src/systems/move-toward.lua index bb0ece1..3777c09 100644 --- a/src/systems/move-toward.lua +++ b/src/systems/move-toward.lua @@ -15,27 +15,24 @@ local function normalizeVector(xy1, xy2) return x / distance, y / distance, distance end -moveTowardSystem = filteredSystem( - { moveToward = MoveToward, position = T.XyPair }, - function(e, dt, system) - local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target) - if distance > e.moveToward.range then - return - end - - -- TODO May be incorrect when signs are mismatched between vel and diff - local xVel = xNorm * e.moveToward.speed * dt - if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then - e.position.x = e.moveToward.target.x - else - e.position.x = e.position.x + xVel - end - - local yVel = yNorm * e.moveToward.speed * dt - if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then - e.position.y = e.moveToward.target.y - else - e.position.y = e.position.y + yVel - end +moveTowardSystem = filteredSystem({ moveToward = MoveToward, position = T.XyPair }, function(e, dt, system) + local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target) + if distance > e.moveToward.range then + return end -) + + -- TODO May be incorrect when signs are mismatched between vel and diff + local xVel = xNorm * e.moveToward.speed * dt + if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then + e.position.x = e.moveToward.target.x + else + e.position.x = e.position.x + xVel + end + + local yVel = yNorm * e.moveToward.speed * dt + if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then + e.position.y = e.moveToward.target.y + else + e.position.y = e.position.y + yVel + end +end) diff --git a/src/systems/rounds.lua b/src/systems/rounds.lua index 344f1f3..3a5ec37 100644 --- a/src/systems/rounds.lua +++ b/src/systems/rounds.lua @@ -22,6 +22,8 @@ roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Mayb stopMovingOnCollision = true, }) + -- TODO: Big ol' numbers displaying how many ingredients were collected? + -- TODO: Could layer ingredients in rows of three? Maybe just when it's higher? local delayPerDrop = 150 local delay = 0 for i, collectable in ipairs(collectedEntities.entities) do @@ -48,30 +50,51 @@ roundSystem = filteredSystem({ roundAction = T.RoundStateAction, position = Mayb end local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3) + -- Sorting from shortest to longest sort of makes them look like a bun? + table.sort(availableUpgrades, function(a, b) + return #a.name > #b.name + end) y = y - 50 + local menuEntity = { + menuItems = {}, + canReceiveInput = T.marker, + } + local upgradeBelow for _, upgrade in ipairs(availableUpgrades) do - printTable(upgrade) - local collX, collY = 75, 30 + local collX, collY = 75, 21 y = y - collY - 15 - playdate.timer.new(delay, function(ee, ccollX, ccollY, yy, ii, ssystem, ccollectable) - ssystem.world:addEntity({ - drawAsText = { - text = upgrade.name, - }, - size = { x = ccollX, y = ccollY / 2 }, - mass = 0.5, - velocity = { x = 0, y = 0 }, - position = { x = ee.position.x - (ccollX / 2), y = yy }, - canCollideWith = 2, - canBeCollidedBy = 2, - isSolid = true, - stopMovingOnCollision = true, - onCollidingRemove = onCollidingRemove, - focusOnCollide = ii, - }) - end, e, collX, collY, y, i, system, collectable) + local upgradeEntity = { + onSelect = upgrade.apply, + drawAsText = { + text = upgrade.name, + style = TextStyle.Inverted, + }, + size = { x = collX, y = collY }, + mass = 0.5, + velocity = { x = 0, y = 0 }, + position = { x = e.position.x, y = y }, + canCollideWith = 2, + canBeCollidedBy = 2, + isSolid = true, + stopMovingOnCollision = true, + onCollidingRemove = onCollidingRemove, + focusOnCollide = i, + navigateDown = upgradeBelow, + highlighted = true, + } + if upgradeBelow then + upgradeBelow.navigateUp = upgradeEntity + upgradeBelow.highlighted = false + upgradeBelow.drawAsText.style = TextStyle.Bordered + end + upgradeBelow = upgradeEntity + menuEntity.menuItems[#menuEntity.menuItems + 1] = upgradeEntity + playdate.timer.new(delay, function(_system, _upgradeEntity) + _system.world:addEntity(_upgradeEntity) + end, system, upgradeEntity) delay = delay + delayPerDrop + system.world:addEntity(menuEntity) end system.world:removeEntity(e) end diff --git a/src/systems/spawner.lua b/src/systems/spawner.lua index 3ff3efb..ed01416 100644 --- a/src/systems/spawner.lua +++ b/src/systems/spawner.lua @@ -109,7 +109,7 @@ function getAvailableSpawnerUpgrades() local upgrades = {} for _, spawner in pairs(spawnerSystem.entities) do if spawner.hasUpgradeSpeed then - upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed } + -- upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed } end if spawner.canSpawn.entity.score then @@ -117,7 +117,7 @@ function getAvailableSpawnerUpgrades() name = "Double " .. spawner.name .. " value", apply = function() spawner.canSpawn.entity.score = spawner.canSpawn.entity.score * 2 - end + end, } end @@ -126,7 +126,8 @@ function getAvailableSpawnerUpgrades() name = "Double " .. spawner.name .. " frequency", apply = function() spawner.odds = spawner.odds * 2 - end + -- addEntity({ roundAction = "NEXT_ROUND" }) + end, } -- if not spawner.canSpawn.entity.velocity then diff --git a/src/systems/velocity.lua b/src/systems/velocity.lua index 8e2ed74..7de745d 100644 --- a/src/systems/velocity.lua +++ b/src/systems/velocity.lua @@ -1,10 +1,7 @@ local sqrt = math.sqrt velocitySystem = filteredSystem({ position = T.XyPair, velocity = T.XyPair }, function(e, dt, system) - if not e.velocity then - return - end - if sqrt((e.velocity.x * e.velocity.x) + (e.velocity.y * e.velocity.y)) < 1.5 then + if sqrt((e.velocity.x * e.velocity.x) + (e.velocity.y * e.velocity.y)) < 2 then e.velocity = nil if e.spawnEntitiesWhenStopped then e:spawnEntitiesWhenStopped(system.world) diff --git a/src/utils.lua b/src/utils.lua index 189eaef..6281b04 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -25,4 +25,4 @@ function Utils.getNDifferentValues(fromArr, n) randoms[#randoms + 1] = fromArr[i] end return randoms -end \ No newline at end of file +end