Get some cart upgrades in there.
Replace "key" => value with a simple object of component replacements.
This commit is contained in:
parent
d6c934a265
commit
23f5ba9f03
|
@ -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
|
|
11
src/cart.lua
11
src/cart.lua
|
@ -12,8 +12,8 @@ function Cart.reset(o)
|
||||||
y = 50,
|
y = 50,
|
||||||
}
|
}
|
||||||
o.velocity = {
|
o.velocity = {
|
||||||
x = 300 + (100 * math.random()),
|
x = o.baseVelocity.x + (100 * math.random()),
|
||||||
y = 175 * (math.random() - 1),
|
y = o.baseVelocity.y * math.random(),
|
||||||
}
|
}
|
||||||
o.size = size
|
o.size = size
|
||||||
o.canBeBounced = {
|
o.canBeBounced = {
|
||||||
|
@ -49,5 +49,10 @@ function Cart.reset(o)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Cart.new()
|
function Cart.new()
|
||||||
return setmetatable(Cart.reset({}), { __index = Cart })
|
return setmetatable(Cart.reset({
|
||||||
|
baseVelocity = {
|
||||||
|
x = 300,
|
||||||
|
y = -170,
|
||||||
|
}
|
||||||
|
}), { __index = Cart })
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,7 @@ import("systems/rounds.lua")
|
||||||
import("systems/camera-pan.lua")
|
import("systems/camera-pan.lua")
|
||||||
import("systems/collision-resolution.lua")
|
import("systems/collision-resolution.lua")
|
||||||
import("systems/collision-detection.lua")
|
import("systems/collision-detection.lua")
|
||||||
|
import("systems/upgrade-utils.lua")
|
||||||
|
|
||||||
import("systems/draw.lua")
|
import("systems/draw.lua")
|
||||||
import("systems/input.lua")
|
import("systems/input.lua")
|
||||||
|
@ -37,7 +38,6 @@ local gfx <const> = playdate.graphics
|
||||||
playdate.display.setRefreshRate(50)
|
playdate.display.setRefreshRate(50)
|
||||||
gfx.setBackgroundColor(gfx.kColorWhite)
|
gfx.setBackgroundColor(gfx.kColorWhite)
|
||||||
|
|
||||||
cart = Cart.new()
|
|
||||||
local floorSize = { x = 10000, y = 10 }
|
local floorSize = { x = 10000, y = 10 }
|
||||||
floor = {
|
floor = {
|
||||||
position = { x = 0, y = 235 },
|
position = { x = 0, y = 235 },
|
||||||
|
@ -67,7 +67,7 @@ function Score:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
world:addEntity(floor)
|
world:addEntity(floor)
|
||||||
world:addEntity(cart)
|
world:addEntity(Cart.new())
|
||||||
addAllSpawners(world)
|
addAllSpawners(world)
|
||||||
|
|
||||||
world:addEntity(Ingredients.getFirst())
|
world:addEntity(Ingredients.getFirst())
|
||||||
|
|
|
@ -13,8 +13,7 @@ local SOME_TABLE <const> = {}
|
||||||
---@alias Entity table
|
---@alias Entity table
|
||||||
---@alias InRelations Entity[]
|
---@alias InRelations Entity[]
|
||||||
---@alias InputState { receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }
|
---@alias InputState { receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }
|
||||||
---@alias ReplaceRelation { entityToModify: Entity, replacement: Replacement }
|
---@alias ReplaceRelation { entityToModify: Entity, replacement: table }
|
||||||
---@alias Replacement { key: string, value: AnyComponent }
|
|
||||||
---@alias RoundStateAction "end" | "start"
|
---@alias RoundStateAction "end" | "start"
|
||||||
---@alias Selectable { additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }
|
---@alias Selectable { additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }
|
||||||
---@alias XyPair { x: number, y: number }
|
---@alias XyPair { x: number, y: number }
|
||||||
|
@ -67,9 +66,6 @@ T = {
|
||||||
---@type ReplaceRelation
|
---@type ReplaceRelation
|
||||||
ReplaceRelation = SOME_TABLE,
|
ReplaceRelation = SOME_TABLE,
|
||||||
|
|
||||||
---@type Replacement
|
|
||||||
Replacement = SOME_TABLE,
|
|
||||||
|
|
||||||
---@type RoundStateAction
|
---@type RoundStateAction
|
||||||
RoundStateAction = "start",
|
RoundStateAction = "start",
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@ local SOME_TABLE <const> = {}
|
||||||
CanBeBounced = "{ flat: XyPair, mult = XyPair }",
|
CanBeBounced = "{ flat: XyPair, mult = XyPair }",
|
||||||
InputState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }",
|
InputState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }",
|
||||||
|
|
||||||
Replacement = "{ key: string, value: AnyComponent }",
|
ReplaceRelation = "{ entityToModify: Entity, replacement: table }",
|
||||||
ReplaceRelation = "{ entityToModify: Entity, replacement: Replacement }",
|
|
||||||
Selectable = "{ additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }",
|
Selectable = "{ additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
---@param relation ReplaceRelation
|
---@param relation ReplaceRelation
|
||||||
---@param world World
|
---@param world World
|
||||||
local function applyReplacementRelation(relation, world)
|
local function applyReplacementRelation(relation, world)
|
||||||
printTable(relation.entityToModify)
|
for k, v in pairs(relation.replacement) do
|
||||||
relation.entityToModify[relation.replacement.key] = relation.replacement.value
|
relation.entityToModify[k] = v
|
||||||
|
end
|
||||||
world:addEntity(relation.entityToModify)
|
world:addEntity(relation.entityToModify)
|
||||||
printTable(relation.entityToModify)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
menuController = filteredSystem("menuController", { menuItems = Arr(T.Selectable), inputState = T.InputState }, function(e, _, system)
|
menuController = filteredSystem("menuController", { menuItems = Arr(T.Selectable), inputState = T.InputState }, function(e, _, system)
|
||||||
|
|
|
@ -102,8 +102,8 @@ roundSystem = filteredSystem("round", { roundAction = T.RoundStateAction, positi
|
||||||
system.world:removeEntity(collectable)
|
system.world:removeEntity(collectable)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type SpawnerUpgrade[]
|
---@type NamedUpgrade[]
|
||||||
local availableUpgrades = Utils.getNDifferentValues(getAvailableSpawnerUpgrades(), 3)
|
local availableUpgrades = Utils.getNDifferentValues(getAvailableUpgrades(), 3)
|
||||||
-- Sorting from shortest to longest sort of makes them look like a bun?
|
-- Sorting from shortest to longest sort of makes them look like a bun?
|
||||||
table.sort(availableUpgrades, function(a, b)
|
table.sort(availableUpgrades, function(a, b)
|
||||||
return #a.name > #b.name
|
return #a.name > #b.name
|
||||||
|
|
|
@ -62,7 +62,7 @@ function addAllSpawners(world)
|
||||||
local size = { x = sizeX, y = sizeY / 2 }
|
local size = { x = sizeX, y = sizeY / 2 }
|
||||||
|
|
||||||
world:addEntity({
|
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.
|
-- It should only be used to supply visual information when searching for available upgrades.
|
||||||
name = name,
|
name = name,
|
||||||
odds = spawnerOdds,
|
odds = spawnerOdds,
|
||||||
|
@ -101,43 +101,3 @@ function addAllSpawners(world)
|
||||||
})
|
})
|
||||||
end
|
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
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue