diff --git a/src/bouncer-coroutine.lua.bak b/src/bouncer-coroutine.lua.bak deleted file mode 100644 index 9fa9c93..0000000 --- a/src/bouncer-coroutine.lua.bak +++ /dev/null @@ -1,42 +0,0 @@ -function bouncer(v) - return function() - local h0 = 0.1 -- m/s - -- local v = 10 -- m/s, current velocity - local g = 10 -- m/s/s - local t = 0 -- starting time - local rho = 0.60 -- coefficient of restitution - local tau = 0.10 -- contact time for bounce - local hmax = h0 -- keep track of the maximum height - local h = h0 - local hstop = 0.01 -- stop when bounce is less than 1 cm - local freefall = true -- state: freefall or in contact - local t_last = -math.sqrt(2 * h0 / g) -- time we would have launched to get to h0 at t=0 - local vmax = math.sqrt(v * g) - - while hmax > hstop do - local dt = coroutine.yield(h, not freefall) - if freefall then - local hnew = h + v * dt - 0.5 * g * dt * dt - if hnew < 0 then - -- Bounced! - t = t_last + 2 * math.sqrt(2 * hmax / g) - freefall = false - t_last = t + tau - h = 0 - else - t = t + dt - v = v - g * dt - h = hnew - end - else - t = t + tau - vmax = vmax * rho - v = vmax - freefall = true - h = 0 - end - hmax = 0.5 * vmax * vmax / g - end - return 0 - end -end diff --git a/src/cart.lua b/src/cart.lua index d1ab3b6..e310826 100644 --- a/src/cart.lua +++ b/src/cart.lua @@ -12,8 +12,8 @@ function Cart.reset(o) y = 50, } o.velocity = { - x = 300 + (100 * math.random()), - y = 175 * (math.random() - 1), + x = o.baseVelocity.x + (100 * math.random()), + y = o.baseVelocity.y * math.random(), } o.size = size o.canBeBounced = { @@ -49,5 +49,10 @@ function Cart.reset(o) end function Cart.new() - return setmetatable(Cart.reset({}), { __index = Cart }) + return setmetatable(Cart.reset({ + baseVelocity = { + x = 300, + y = -170, + } + }), { __index = Cart }) end diff --git a/src/main.lua b/src/main.lua index c32b07b..3c9d874 100644 --- a/src/main.lua +++ b/src/main.lua @@ -24,6 +24,7 @@ import("systems/rounds.lua") import("systems/camera-pan.lua") import("systems/collision-resolution.lua") import("systems/collision-detection.lua") +import("systems/upgrade-utils.lua") import("systems/draw.lua") import("systems/input.lua") @@ -37,7 +38,6 @@ local gfx = playdate.graphics playdate.display.setRefreshRate(50) gfx.setBackgroundColor(gfx.kColorWhite) -cart = Cart.new() local floorSize = { x = 10000, y = 10 } floor = { position = { x = 0, y = 235 }, @@ -67,7 +67,7 @@ function Score:draw() end world:addEntity(floor) -world:addEntity(cart) +world:addEntity(Cart.new()) addAllSpawners(world) world:addEntity(Ingredients.getFirst()) diff --git a/src/systems/filter-types.lua b/src/systems/filter-types.lua index 3be261b..ca2dad3 100644 --- a/src/systems/filter-types.lua +++ b/src/systems/filter-types.lua @@ -13,8 +13,7 @@ local SOME_TABLE = {} ---@alias Entity table ---@alias InRelations Entity[] ---@alias InputState { receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean } ----@alias ReplaceRelation { entityToModify: Entity, replacement: Replacement } ----@alias Replacement { key: string, value: AnyComponent } +---@alias ReplaceRelation { entityToModify: Entity, replacement: table } ---@alias RoundStateAction "end" | "start" ---@alias Selectable { additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil } ---@alias XyPair { x: number, y: number } @@ -67,9 +66,6 @@ T = { ---@type ReplaceRelation ReplaceRelation = SOME_TABLE, - ---@type Replacement - Replacement = SOME_TABLE, - ---@type RoundStateAction RoundStateAction = "start", diff --git a/src/systems/filter-types.lua2p b/src/systems/filter-types.lua2p index 7d7ebe4..a436829 100644 --- a/src/systems/filter-types.lua2p +++ b/src/systems/filter-types.lua2p @@ -66,8 +66,7 @@ local SOME_TABLE = {} CanBeBounced = "{ flat: XyPair, mult = XyPair }", InputState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }", - Replacement = "{ key: string, value: AnyComponent }", - ReplaceRelation = "{ entityToModify: Entity, replacement: Replacement }", + ReplaceRelation = "{ entityToModify: Entity, replacement: table }", Selectable = "{ additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }", })) diff --git a/src/systems/menu.lua b/src/systems/menu.lua index 6108581..7a7a31b 100644 --- a/src/systems/menu.lua +++ b/src/systems/menu.lua @@ -1,10 +1,10 @@ ---@param relation ReplaceRelation ---@param world World local function applyReplacementRelation(relation, world) - printTable(relation.entityToModify) - relation.entityToModify[relation.replacement.key] = relation.replacement.value + for k, v in pairs(relation.replacement) do + relation.entityToModify[k] = v + end world:addEntity(relation.entityToModify) - printTable(relation.entityToModify) end menuController = filteredSystem("menuController", { menuItems = Arr(T.Selectable), inputState = T.InputState }, function(e, _, system) diff --git a/src/systems/rounds.lua b/src/systems/rounds.lua index 823f16b..6829edb 100644 --- a/src/systems/rounds.lua +++ b/src/systems/rounds.lua @@ -102,8 +102,8 @@ roundSystem = filteredSystem("round", { roundAction = T.RoundStateAction, positi system.world:removeEntity(collectable) end - ---@type SpawnerUpgrade[] - local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3) + ---@type NamedUpgrade[] + local availableUpgrades = Utils.getNDifferentValues(getAvailableUpgrades(), 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 diff --git a/src/systems/spawner.lua b/src/systems/spawner.lua index 30c5117..cc031f6 100644 --- a/src/systems/spawner.lua +++ b/src/systems/spawner.lua @@ -62,7 +62,7 @@ function addAllSpawners(world) local size = { x = sizeX, y = sizeY / 2 } world:addEntity({ - -- NOTE: This name should NOT be used to identify the spawner. + -- NOTE: This name should NOT be used to *identify* the spawner. -- It should only be used to supply visual information when searching for available upgrades. name = name, odds = spawnerOdds, @@ -101,43 +101,3 @@ function addAllSpawners(world) }) end ----@alias SpawnerUpgrade { name: string, replace: ReplaceRelation } - ----@return SpawnerUpgrade[] -function getAvailableSpawnerUpgrades() - ---@type SpawnerUpgrade[] - local upgrades = {} - for _, spawner in pairs(spawnerSystem.entities) do - -- if spawner.hasUpgradeSpeed then - -- upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed } - -- end - - local entityToSpawn = spawner.canSpawn.entityToSpawn - if entityToSpawn.score then - upgrades[#upgrades + 1] = { - name = "Double " .. spawner.name .. " value", - replace = { - entityToModify = entityToSpawn, - replacement = { - key = "score", - value = entityToSpawn.score * 2, - }, - }, - } - end - - assert(spawner.odds, "Expected all spawners to have an `odds` field!") - upgrades[#upgrades + 1] = { - name = "Double " .. spawner.name .. " frequency", - replace = { - entityToModify = entityToSpawn, - replacement = { - key = "odds", - value = entityToSpawn.odds, - } - }, - } - end - - return upgrades -end diff --git a/src/systems/upgrade-utils.lua b/src/systems/upgrade-utils.lua new file mode 100644 index 0000000..edfd435 --- /dev/null +++ b/src/systems/upgrade-utils.lua @@ -0,0 +1,77 @@ +---@alias NamedUpgrade { name: string, replace: ReplaceRelation } + +--- Appends available upgrades to the given upgrades array. +---@param upgrades NamedUpgrade[] +function getAvailableSpawnerUpgrades(upgrades) + for _, spawner in pairs(spawnerSystem.entities) do + -- if spawner.hasUpgradeSpeed then + -- upgrades[#upgrades + 1] = { hasUpgradeSpeed = spawner.hasUpgradeSpeed } + -- end + + local entityToSpawn = spawner.canSpawn.entityToSpawn + if entityToSpawn.score then + upgrades[#upgrades + 1] = { + name = "Double " .. spawner.name .. " value", + replace = { + entityToModify = entityToSpawn, + replacement = { + score = entityToSpawn.score * 2, + }, + }, + } + end + + assert(spawner.odds, "Expected all spawners to have an `odds` field!") + upgrades[#upgrades + 1] = { + name = "Double " .. spawner.name .. " frequency", + replace = { + entityToModify = spawner, + replacement = { + odds = spawner.odds, + } + }, + } + end +end + +--- Appends available upgrades to the given upgrades array. +---@param upgrades NamedUpgrade[] +function getAvailableCartUpgrades(upgrades) + for _, cart in pairs(cartSystem.entities) do + upgrades[#upgrades + 1] = { + name = "10% Lighter Cart", + replace = { + entityToModify = cart, + replacement = { + mass = cart.mass * 0.9 + } + }, + } + upgrades[#upgrades + 1] = { + name = "+20% Cart Launch Right", + replace = { + entityToModify = cart.baseVelocity, + replacement = { + x = cart.baseVelocity.x * 1.2 + } + }, + } + upgrades[#upgrades + 1] = { + name = "+20% Cart Launch Up", + replace = { + entityToModify = cart.baseVelocity, + replacement = { + y = cart.baseVelocity.y * 1.2 + } + }, + } + end +end + +---@return NamedUpgrade[] +function getAvailableUpgrades() + local upgrades = {} + getAvailableSpawnerUpgrades(upgrades) + getAvailableCartUpgrades(upgrades) + return upgrades +end