Replace collectableDrop and afterDelayAdd systems with collision-chaining.
Waits for one entity to collide to enable collision on the next entity in the chain.
This commit is contained in:
parent
23f5ba9f03
commit
9f71874272
|
@ -3,7 +3,7 @@ if not playdate.isSimulator then
|
||||||
end
|
end
|
||||||
getCurrentTimeMilliseconds = playdate.getCurrentTimeMilliseconds
|
getCurrentTimeMilliseconds = playdate.getCurrentTimeMilliseconds
|
||||||
|
|
||||||
tinyTrackEntityAges = true
|
tinyTrackEntityAges = false
|
||||||
ENTITY_INIT_MS = { "ENTITY_INIT_MS" }
|
ENTITY_INIT_MS = { "ENTITY_INIT_MS" }
|
||||||
|
|
||||||
if tinyTrackEntityAges then
|
if tinyTrackEntityAges then
|
||||||
|
@ -12,7 +12,7 @@ if tinyTrackEntityAges then
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tinyLogSystemUpdateTime = false
|
tinyLogSystemUpdateTime = true
|
||||||
tinyLogSystemChanges = false
|
tinyLogSystemChanges = false
|
||||||
|
|
||||||
tinyWarnWhenNonDataOnEntities = false
|
tinyWarnWhenNonDataOnEntities = false
|
||||||
|
|
15
src/cart.lua
15
src/cart.lua
|
@ -49,10 +49,13 @@ function Cart.reset(o)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Cart.new()
|
function Cart.new()
|
||||||
return setmetatable(Cart.reset({
|
return setmetatable(
|
||||||
baseVelocity = {
|
Cart.reset({
|
||||||
x = 300,
|
baseVelocity = {
|
||||||
y = -170,
|
x = 300,
|
||||||
}
|
y = -170,
|
||||||
}), { __index = Cart })
|
},
|
||||||
|
}),
|
||||||
|
{ __index = Cart }
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
45
src/main.lua
45
src/main.lua
|
@ -67,7 +67,27 @@ function Score:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
world:addEntity(floor)
|
world:addEntity(floor)
|
||||||
world:addEntity(Cart.new())
|
|
||||||
|
local scenarios = {
|
||||||
|
default = function()
|
||||||
|
world:addEntity(Cart.new())
|
||||||
|
end ,
|
||||||
|
manyCollectables = function()
|
||||||
|
local cart = Cart.new()
|
||||||
|
cart.velocity.x = 0
|
||||||
|
cart.velocity.y = 1
|
||||||
|
cart.position.x = 200
|
||||||
|
cart.position.y = 200
|
||||||
|
world:addEntity(cart)
|
||||||
|
local collectables = { LettuceSprite, TomatoSprite, MushroomSprite, CheeseSprite }
|
||||||
|
for _ = 1, 200 do
|
||||||
|
world:addEntity({ collected = collectables[math.random(#collectables)] })
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios.manyCollectables()
|
||||||
|
|
||||||
addAllSpawners(world)
|
addAllSpawners(world)
|
||||||
|
|
||||||
world:addEntity(Ingredients.getFirst())
|
world:addEntity(Ingredients.getFirst())
|
||||||
|
@ -77,6 +97,29 @@ playdate.setAutoLockDisabled(true)
|
||||||
|
|
||||||
local startMsOffset = -playdate.getCurrentTimeMilliseconds()
|
local startMsOffset = -playdate.getCurrentTimeMilliseconds()
|
||||||
|
|
||||||
|
-- local maxBatcherLength = 10
|
||||||
|
-- local root = {}
|
||||||
|
-- local physicsGroup = root
|
||||||
|
--
|
||||||
|
-- function append(element)
|
||||||
|
-- if #physicsGroup < maxBatcherLength then
|
||||||
|
-- physicsGroup[#physicsGroup + 1] = element
|
||||||
|
-- else
|
||||||
|
-- physicsGroup = { element }
|
||||||
|
-- root[#root + 1] = physicsGroup
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- for i = 1, 25 do
|
||||||
|
-- append(i)
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- for i = 1, 10 do
|
||||||
|
--
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- printTable(root)
|
||||||
|
|
||||||
function playdate.update()
|
function playdate.update()
|
||||||
local deltaSeconds = playdate.getElapsedTime()
|
local deltaSeconds = playdate.getElapsedTime()
|
||||||
playdate.resetElapsedTime()
|
playdate.resetElapsedTime()
|
||||||
|
|
|
@ -29,7 +29,6 @@ function cameraPanSystem:postProcess()
|
||||||
|
|
||||||
for _, entity in pairs(expireBelowScreenSystem.entities) do
|
for _, entity in pairs(expireBelowScreenSystem.entities) do
|
||||||
if entity.position.y - (Camera.pan.y + 240) > entity.expireBelowScreenBy then
|
if entity.position.y - (Camera.pan.y + 240) > entity.expireBelowScreenBy then
|
||||||
print("Entity expired - was too far below screen!")
|
|
||||||
self.world:removeEntity(entity)
|
self.world:removeEntity(entity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,12 +6,18 @@ collidingEntities = filteredSystem("collidingEntitites", {
|
||||||
isSolid = Maybe(T.bool),
|
isSolid = Maybe(T.bool),
|
||||||
})
|
})
|
||||||
|
|
||||||
collisionDetection = filteredSystem("collisionDetection",
|
collisionDetection = filteredSystem(
|
||||||
|
"collisionDetection",
|
||||||
{ position = T.XyPair, size = T.XyPair, canBeCollidedBy = T.BitMask, isSolid = Maybe(T.bool) },
|
{ position = T.XyPair, size = T.XyPair, canBeCollidedBy = T.BitMask, isSolid = Maybe(T.bool) },
|
||||||
-- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
|
-- Here, the entity, e, refers to some entity that a moving object may be colliding *into*
|
||||||
function(e, _, system)
|
function(e, _, system)
|
||||||
for _, collider in pairs(collidingEntities.entities) do
|
for _, collider in pairs(collidingEntities.entities) do
|
||||||
if (e ~= collider) and collider.canCollideWith and e.canBeCollidedBy and ((collider.canCollideWith & e.canBeCollidedBy) ~= 0) then
|
if
|
||||||
|
(e ~= collider)
|
||||||
|
and collider.canCollideWith
|
||||||
|
and e.canBeCollidedBy
|
||||||
|
and ((collider.canCollideWith & e.canBeCollidedBy) ~= 0)
|
||||||
|
then
|
||||||
local colliderTop = collider.position.y
|
local colliderTop = collider.position.y
|
||||||
local colliderBottom = collider.position.y + collider.size.y
|
local colliderBottom = collider.position.y + collider.size.y
|
||||||
local entityTop = e.position.y
|
local entityTop = e.position.y
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
---@alias CollisionChain { entityToGiveCollision: Entity, canCollideWith: BitMask, canBeCollidedBy: BitMask }
|
||||||
|
|
||||||
collisionResolution = filteredSystem("collisionResolution", { collisionBetween = T.Collision }, function(e, dt, system)
|
collisionResolution = filteredSystem("collisionResolution", { collisionBetween = T.Collision }, function(e, dt, system)
|
||||||
local collidedInto, collider = e.collisionBetween[1], e.collisionBetween[2]
|
local collidedInto, collider = e.collisionBetween[1], e.collisionBetween[2]
|
||||||
local colliderTop = collidedInto.position.y
|
local colliderTop = collidedInto.position.y
|
||||||
|
@ -20,6 +22,14 @@ collisionResolution = filteredSystem("collisionResolution", { collisionBetween =
|
||||||
collider.velocity.y = collider.velocity.y * collidedInto.canBounce.mult.y * collider.canBeBounced.mult.y
|
collider.velocity.y = collider.velocity.y * collidedInto.canBounce.mult.y * collider.canBeBounced.mult.y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if collider.collisionChain then
|
||||||
|
---@type CollisionChain
|
||||||
|
local chain = collider.collisionChain
|
||||||
|
chain.entityToGiveCollision.canCollideWith = chain.canCollideWith
|
||||||
|
chain.entityToGiveCollision.canBeCollidedBy = chain.canBeCollidedBy
|
||||||
|
system.world:addEntity(chain.entityToGiveCollision)
|
||||||
|
end
|
||||||
|
|
||||||
if collider.focusOnCollide then
|
if collider.focusOnCollide then
|
||||||
system.world:addEntity({
|
system.world:addEntity({
|
||||||
removeAtRoundStart = true,
|
removeAtRoundStart = true,
|
||||||
|
|
|
@ -1,16 +1,28 @@
|
||||||
local gfx <const> = playdate.graphics
|
local gfx <const> = playdate.graphics
|
||||||
|
|
||||||
drawRectanglesSystem = filteredSystem("drawRectangles", { position = T.XyPair, drawAsRectangle = { size = T.XyPair } }, function(e, dt)
|
drawRectanglesSystem = filteredSystem(
|
||||||
gfx.fillRect(e.position.x, e.position.y, e.drawAsRectangle.size.x, e.drawAsRectangle.size.y)
|
"drawRectangles",
|
||||||
end)
|
{ position = T.XyPair, drawAsRectangle = { size = T.XyPair } },
|
||||||
|
function(e, dt)
|
||||||
|
gfx.fillRect(e.position.x, e.position.y, e.drawAsRectangle.size.x, e.drawAsRectangle.size.y)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
drawSpriteSystem = filteredSystem("drawSprites", { position = T.XyPair, drawAsSprite = T.pd_image }, function(e, dt, system)
|
drawSpriteSystem = filteredSystem(
|
||||||
e.drawAsSprite:draw(e.position.x, e.position.y)
|
"drawSprites",
|
||||||
end)
|
{ position = T.XyPair, drawAsSprite = T.pd_image },
|
||||||
|
function(e)
|
||||||
|
if e.position.y < Camera.pan.y - 240 or e.position.y > Camera.pan.y + 480 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
e.drawAsSprite:draw(e.position.x, e.position.y)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
local xMargin = 4
|
local xMargin = 4
|
||||||
|
|
||||||
drawTextSystem = filteredSystem("drawText",
|
drawTextSystem = filteredSystem(
|
||||||
|
"drawText",
|
||||||
{ position = T.XyPair, drawAsText = { text = T.str, style = Maybe(T.str), font = Maybe(T.pd_font) } },
|
{ position = T.XyPair, drawAsText = { text = T.str, style = Maybe(T.str), font = Maybe(T.pd_font) } },
|
||||||
function(e)
|
function(e)
|
||||||
local font = e.drawAsText.font or AshevilleSans14Bold
|
local font = e.drawAsText.font or AshevilleSans14Bold
|
||||||
|
|
|
@ -8,8 +8,10 @@ filteredSystem("changeGravity", { changeGravityTo = T.number }, function(e, _, _
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local min = math.min
|
||||||
|
|
||||||
fallSystem = filteredSystem("fall", { velocity = T.XyPair, mass = T.number }, function(e, dt)
|
fallSystem = filteredSystem("fall", { velocity = T.XyPair, mass = T.number }, function(e, dt)
|
||||||
for _, ge in pairs(gravities.entities) do
|
for _, ge in pairs(gravities.entities) do
|
||||||
e.velocity.y = e.velocity.y - (ge.gravity * dt * e.mass) - (0.5 * dt * dt)
|
e.velocity.y = min(400, e.velocity.y - (ge.gravity * dt * e.mass) - (0.5 * dt * dt))
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -16,8 +16,7 @@ function inputSystem:preProcess()
|
||||||
inputState.aJustPressed = buttonJustPressed(playdate.kButtonA)
|
inputState.aJustPressed = buttonJustPressed(playdate.kButtonA)
|
||||||
inputState.bJustPressed = buttonJustPressed(playdate.kButtonB)
|
inputState.bJustPressed = buttonJustPressed(playdate.kButtonB)
|
||||||
|
|
||||||
inputState.receivedInputThisFrame =
|
inputState.receivedInputThisFrame = inputState.upJustPressed
|
||||||
inputState.upJustPressed
|
|
||||||
or inputState.downJustPressed
|
or inputState.downJustPressed
|
||||||
or inputState.rightJustPressed
|
or inputState.rightJustPressed
|
||||||
or inputState.leftJustPressed
|
or inputState.leftJustPressed
|
||||||
|
|
|
@ -7,50 +7,54 @@ local function applyReplacementRelation(relation, world)
|
||||||
world:addEntity(relation.entityToModify)
|
world:addEntity(relation.entityToModify)
|
||||||
end
|
end
|
||||||
|
|
||||||
menuController = filteredSystem("menuController", { menuItems = Arr(T.Selectable), inputState = T.InputState }, function(e, _, system)
|
menuController = filteredSystem(
|
||||||
for _, menuItem in pairs(e.menuItems) do
|
"menuController",
|
||||||
if menuItem.highlighted then
|
{ menuItems = Arr(T.Selectable), inputState = T.InputState },
|
||||||
if e.inputState.aJustPressed then
|
function(e, _, system)
|
||||||
-- Prepare to remove the menu and all menu items
|
for _, menuItem in pairs(e.menuItems) do
|
||||||
system.world:removeEntity(e)
|
if menuItem.highlighted then
|
||||||
for _, item in pairs(e.menuItems) do
|
if e.inputState.aJustPressed then
|
||||||
system.world:removeEntity(item)
|
-- Prepare to remove the menu and all menu items
|
||||||
end
|
system.world:removeEntity(e)
|
||||||
|
for _, item in pairs(e.menuItems) do
|
||||||
|
system.world:removeEntity(item)
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO: Larger menu that stays open for more purchases before the next round
|
-- TODO: Larger menu that stays open for more purchases before the next round
|
||||||
world:addEntity({ roundAction = "start" })
|
world:addEntity({ roundAction = "start" })
|
||||||
|
|
||||||
if menuItem.replacements then
|
if menuItem.replacements then
|
||||||
for _, v in ipairs(menuItem.replacements) do
|
for _, v in ipairs(menuItem.replacements) do
|
||||||
applyReplacementRelation(v, system.world)
|
applyReplacementRelation(v, system.world)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if menuItem.additions then
|
||||||
|
for _, v in ipairs(menuItem.additions) do
|
||||||
|
system.world:addEntity(v)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if menuItem.additions then
|
|
||||||
for _, v in ipairs(menuItem.additions) do
|
if e.inputState.downJustPressed and menuItem.navigateDown then
|
||||||
system.world:addEntity(v)
|
menuItem.highlighted = false
|
||||||
end
|
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
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if e.inputState.downJustPressed and menuItem.navigateDown then
|
for _, menuItem in pairs(e.menuItems) do
|
||||||
menuItem.highlighted = false
|
if menuItem.highlighted then
|
||||||
menuItem.navigateDown.highlighted = true
|
menuItem.drawAsText.style = TextStyle.Inverted
|
||||||
return
|
else
|
||||||
end
|
menuItem.drawAsText.style = TextStyle.Bordered
|
||||||
|
|
||||||
if e.inputState.upJustPressed and menuItem.navigateUp then
|
|
||||||
menuItem.highlighted = false
|
|
||||||
menuItem.navigateUp.highlighted = true
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end
|
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)
|
|
||||||
|
|
|
@ -15,24 +15,28 @@ local function normalizeVector(xy1, xy2)
|
||||||
return x / distance, y / distance, distance
|
return x / distance, y / distance, distance
|
||||||
end
|
end
|
||||||
|
|
||||||
moveTowardSystem = filteredSystem("moveToward", { moveToward = MoveToward, position = T.XyPair }, function(e, dt, system)
|
moveTowardSystem = filteredSystem(
|
||||||
local xNorm, yNorm, distance = normalizeVector(e.position, e.moveToward.target)
|
"moveToward",
|
||||||
if distance > e.moveToward.range then
|
{ moveToward = MoveToward, position = T.XyPair },
|
||||||
return
|
function(e, dt, system)
|
||||||
end
|
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
|
-- TODO May be incorrect when signs are mismatched between vel and diff
|
||||||
local xVel = xNorm * e.moveToward.speed * dt
|
local xVel = xNorm * e.moveToward.speed * dt
|
||||||
if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then
|
if abs(e.position.x - e.moveToward.target.x) < abs(xVel) then
|
||||||
e.position.x = e.moveToward.target.x
|
e.position.x = e.moveToward.target.x
|
||||||
else
|
else
|
||||||
e.position.x = e.position.x + xVel
|
e.position.x = e.position.x + xVel
|
||||||
end
|
end
|
||||||
|
|
||||||
local yVel = yNorm * e.moveToward.speed * dt
|
local yVel = yNorm * e.moveToward.speed * dt
|
||||||
if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then
|
if abs(e.position.y - e.moveToward.target.y) < abs(yVel) then
|
||||||
e.position.y = e.moveToward.target.y
|
e.position.y = e.moveToward.target.y
|
||||||
else
|
else
|
||||||
e.position.y = e.position.y + yVel
|
e.position.y = e.position.y + yVel
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
)
|
||||||
|
|
|
@ -2,160 +2,139 @@ collectedEntities = filteredSystem("collectedEntities", { collected = T.pd_image
|
||||||
|
|
||||||
local onCollidingRemove = { "mass", "velocity", "canCollideWith" }
|
local onCollidingRemove = { "mass", "velocity", "canCollideWith" }
|
||||||
|
|
||||||
local Drop = { i = T.number, delay = T.number, startAt = T.XyPair }
|
disableCollisionWhenRoundEnds =
|
||||||
|
filteredSystem("disableCollisionWhenRoundEnds", { disableCollisionWhenRoundEnds = T.marker })
|
||||||
disableCollisionWhenRoundEnds = filteredSystem("disableCollisionWhenRoundEnds", { disableCollisionWhenRoundEnds = T.marker })
|
|
||||||
|
|
||||||
collectableDropSystem = filteredSystem("collectableDrop", { drop = Drop }, function(e, dt, system)
|
|
||||||
e.drop.delay = e.drop.delay - dt
|
|
||||||
if e.drop.delay > 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local collX, collY = e.drop.sprite:getSize()
|
|
||||||
system.world:addEntity({
|
|
||||||
drawAsSprite = e.drop.sprite,
|
|
||||||
size = { x = collX, y = collY / 2 },
|
|
||||||
mass = 0.5,
|
|
||||||
velocity = { x = 0, y = 0 },
|
|
||||||
position = { x = e.drop.startAt.x - (collX / 2), y = e.drop.startAt.y },
|
|
||||||
canCollideWith = 2,
|
|
||||||
canBeCollidedBy = 2,
|
|
||||||
isSolid = true,
|
|
||||||
stopMovingOnCollision = true,
|
|
||||||
onCollidingRemove = onCollidingRemove,
|
|
||||||
focusOnCollide = e.drop.i,
|
|
||||||
expireBelowScreenBy = 5,
|
|
||||||
removeAtRoundStart = true,
|
|
||||||
})
|
|
||||||
system.world:removeEntity(e)
|
|
||||||
end)
|
|
||||||
|
|
||||||
removeAtRoundStart = filteredSystem("removeAtRoundStart", { removeAtRoundStart = T.bool })
|
removeAtRoundStart = filteredSystem("removeAtRoundStart", { removeAtRoundStart = T.bool })
|
||||||
|
|
||||||
filteredSystem("afterDelayAdd", { afterDelayAdd = { entityToAdd = T.Entity, delay = T.number } }, function(e, dt, system)
|
roundSystem = filteredSystem(
|
||||||
e.afterDelayAdd.delay = e.afterDelayAdd.delay - dt
|
"round",
|
||||||
if e.afterDelayAdd.delay > 0 then
|
{ roundAction = T.RoundStateAction, position = Maybe(T.XyPair) },
|
||||||
return
|
function(e, _, system)
|
||||||
end
|
system.world:removeEntity(e)
|
||||||
system.world:addEntity(e.afterDelayAdd.entityToAdd)
|
if e.roundAction == "start" then
|
||||||
system.world:removeEntity(e)
|
for _, cart in pairs(cartSystem.entities) do
|
||||||
end)
|
Cart.reset(cart)
|
||||||
|
system.world:addEntity(cart)
|
||||||
|
end
|
||||||
|
for _, remove in pairs(removeAtRoundStart.entities) do
|
||||||
|
system.world:removeEntity(remove)
|
||||||
|
end
|
||||||
|
system.world:addSystem(spawnerSystem)
|
||||||
|
Ingredients.clearCache(system.world)
|
||||||
|
elseif e.roundAction == "end" then
|
||||||
|
system.world:removeSystem(spawnerSystem)
|
||||||
|
for _, toExpire in pairs(disableCollisionWhenRoundEnds.entities) do
|
||||||
|
toExpire.canCollideWith = nil
|
||||||
|
toExpire.canBeCollidedBy = nil
|
||||||
|
system.world:removeEntity(toExpire)
|
||||||
|
end
|
||||||
|
-- playdate.setAutoLockDisabled(false)
|
||||||
|
|
||||||
roundSystem = filteredSystem("round", { roundAction = T.RoundStateAction, position = Maybe(T.XyPair) }, function(e, _, system)
|
local y = e.position.y - 240
|
||||||
system.world:removeEntity(e)
|
local rectWidth = 150
|
||||||
if e.roundAction == "start" then
|
local plateSize = { x = rectWidth, y = 10 }
|
||||||
for _, cart in pairs(cartSystem.entities) do
|
|
||||||
Cart.reset(cart)
|
|
||||||
system.world:addEntity(cart)
|
|
||||||
end
|
|
||||||
for _, remove in pairs(removeAtRoundStart.entities) do
|
|
||||||
system.world:removeEntity(remove)
|
|
||||||
end
|
|
||||||
system.world:addSystem(spawnerSystem)
|
|
||||||
Ingredients.clearCache(system.world)
|
|
||||||
elseif e.roundAction == "end" then
|
|
||||||
system.world:removeSystem(spawnerSystem)
|
|
||||||
for _, toExpire in pairs(disableCollisionWhenRoundEnds.entities) do
|
|
||||||
toExpire.canCollideWith = nil
|
|
||||||
toExpire.canBeCollidedBy = nil
|
|
||||||
--system.world:addEntity(toExpire)
|
|
||||||
system.world:removeEntity(toExpire)
|
|
||||||
end
|
|
||||||
-- playdate.setAutoLockDisabled(false)
|
|
||||||
|
|
||||||
local y = e.position.y - 240
|
|
||||||
local rectWidth = 150
|
|
||||||
local plateSize = { x = rectWidth, y = 10 }
|
|
||||||
|
|
||||||
system.world:addEntity({
|
|
||||||
drawAsRectangle = { size = plateSize },
|
|
||||||
size = plateSize,
|
|
||||||
mass = 0.5,
|
|
||||||
velocity = { x = 0, y = 0 },
|
|
||||||
position = { x = e.position.x - (rectWidth / 2), y = y },
|
|
||||||
canCollideWith = 2,
|
|
||||||
canBeCollidedBy = 2,
|
|
||||||
isSolid = true,
|
|
||||||
stopMovingOnCollision = true,
|
|
||||||
removeAtRoundStart = 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 = 0.100
|
|
||||||
local delay = 0
|
|
||||||
for i, collectable in ipairs(collectedEntities.entities) do
|
|
||||||
local _, collY = collectable.collected:getSize()
|
|
||||||
y = y - collY - 15
|
|
||||||
system.world:addEntity({
|
system.world:addEntity({
|
||||||
drop = {
|
drawAsRectangle = { size = plateSize },
|
||||||
sprite = collectable.collected,
|
size = plateSize,
|
||||||
i = i,
|
|
||||||
delay = delay,
|
|
||||||
startAt = {
|
|
||||||
x = e.position.x,
|
|
||||||
y = y
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
delay = delay + delayPerDrop
|
|
||||||
system.world:removeEntity(collectable)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@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
|
|
||||||
end)
|
|
||||||
|
|
||||||
y = y - 50
|
|
||||||
local menuEntity = {
|
|
||||||
menuItems = {},
|
|
||||||
canReceiveInput = T.marker,
|
|
||||||
}
|
|
||||||
local upgradeBelow
|
|
||||||
local i = #collectedEntities.entities
|
|
||||||
for _, upgrade in ipairs(availableUpgrades) do
|
|
||||||
i = i + 1
|
|
||||||
local collX, collY = 75, 21
|
|
||||||
y = y - collY - 15 - 15
|
|
||||||
---@type Selectable
|
|
||||||
local upgradeEntity = {
|
|
||||||
replacements = { upgrade.replace },
|
|
||||||
drawAsText = {
|
|
||||||
text = upgrade.name,
|
|
||||||
style = TextStyle.Inverted,
|
|
||||||
},
|
|
||||||
size = { x = collX, y = collY },
|
|
||||||
mass = 0.5,
|
mass = 0.5,
|
||||||
velocity = { x = 0, y = 0 },
|
velocity = { x = 0, y = 0 },
|
||||||
position = { x = e.position.x, y = y },
|
position = { x = e.position.x - (rectWidth / 2), y = y },
|
||||||
canCollideWith = 2,
|
canCollideWith = 2,
|
||||||
canBeCollidedBy = 2,
|
canBeCollidedBy = 2,
|
||||||
isSolid = true,
|
isSolid = true,
|
||||||
stopMovingOnCollision = true,
|
stopMovingOnCollision = true,
|
||||||
onCollidingRemove = onCollidingRemove,
|
|
||||||
focusOnCollide = i,
|
|
||||||
navigateDown = upgradeBelow,
|
|
||||||
highlighted = true,
|
|
||||||
removeAtRoundStart = true,
|
removeAtRoundStart = true,
|
||||||
}
|
|
||||||
if upgradeBelow then
|
|
||||||
upgradeBelow.navigateUp = upgradeEntity
|
|
||||||
upgradeBelow.highlighted = false
|
|
||||||
upgradeBelow.drawAsText.style = TextStyle.Bordered
|
|
||||||
end
|
|
||||||
upgradeBelow = upgradeEntity
|
|
||||||
menuEntity.menuItems[#menuEntity.menuItems + 1] = upgradeEntity
|
|
||||||
delay = delay + delayPerDrop
|
|
||||||
system.world:addEntity({
|
|
||||||
afterDelayAdd = {
|
|
||||||
delay = delay,
|
|
||||||
entityToAdd = upgradeEntity
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
system.world:addEntity(menuEntity)
|
|
||||||
|
-- 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 = 0.100
|
||||||
|
local previousEntity
|
||||||
|
local collectables = collectedEntities.entities
|
||||||
|
for i, collectable in ipairs(collectables) do
|
||||||
|
local collX, collY = collectable.collected:getSize()
|
||||||
|
y = y - collY - 15
|
||||||
|
local currentEntity = {
|
||||||
|
drawAsSprite = collectable.collected,
|
||||||
|
size = { x = collX, y = collY / 2 },
|
||||||
|
mass = 0.5,
|
||||||
|
velocity = { x = 0, y = 0 },
|
||||||
|
position = { x = e.position.x - (collX / 2), y = y },
|
||||||
|
isSolid = true,
|
||||||
|
stopMovingOnCollision = true,
|
||||||
|
onCollidingRemove = onCollidingRemove,
|
||||||
|
focusOnCollide = i,
|
||||||
|
expireBelowScreenBy = 5,
|
||||||
|
removeAtRoundStart = true,
|
||||||
|
}
|
||||||
|
if previousEntity then
|
||||||
|
-- Don't enable collision on this drop until the previous entity collides.
|
||||||
|
previousEntity.collisionChain = {
|
||||||
|
entityToGiveCollision = currentEntity,
|
||||||
|
canCollideWith = 2,
|
||||||
|
canBeCollidedBy = 2,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
-- Enable collision on the first entity
|
||||||
|
currentEntity.canBeCollidedBy = 2
|
||||||
|
currentEntity.canCollideWith = 2
|
||||||
|
end
|
||||||
|
previousEntity = currentEntity
|
||||||
|
system.world:addEntity(currentEntity)
|
||||||
|
system.world:removeEntity(collectable)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@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
|
||||||
|
end)
|
||||||
|
|
||||||
|
y = y - 50
|
||||||
|
local menuEntity = {
|
||||||
|
menuItems = {},
|
||||||
|
canReceiveInput = T.marker,
|
||||||
|
}
|
||||||
|
local upgradeBelow
|
||||||
|
local i = #collectedEntities.entities
|
||||||
|
for _, upgrade in ipairs(availableUpgrades) do
|
||||||
|
i = i + 1
|
||||||
|
local collX, collY = 75, 21
|
||||||
|
y = y - collY - 15 - 15
|
||||||
|
---@type Selectable
|
||||||
|
local upgradeEntity = {
|
||||||
|
replacements = { upgrade.replace },
|
||||||
|
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,
|
||||||
|
removeAtRoundStart = true,
|
||||||
|
}
|
||||||
|
if upgradeBelow then
|
||||||
|
upgradeBelow.navigateUp = upgradeEntity
|
||||||
|
upgradeBelow.highlighted = false
|
||||||
|
upgradeBelow.drawAsText.style = TextStyle.Bordered
|
||||||
|
end
|
||||||
|
upgradeBelow = upgradeEntity
|
||||||
|
menuEntity.menuItems[#menuEntity.menuItems + 1] = upgradeEntity
|
||||||
|
system.world:addEntity(upgradeEntity)
|
||||||
|
system.world:addEntity(menuEntity)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
)
|
||||||
|
|
|
@ -100,4 +100,3 @@ function addAllSpawners(world)
|
||||||
mult = { x = 0.7, y = -0.5 },
|
mult = { x = 0.7, y = -0.5 },
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ function getAvailableSpawnerUpgrades(upgrades)
|
||||||
entityToModify = spawner,
|
entityToModify = spawner,
|
||||||
replacement = {
|
replacement = {
|
||||||
odds = spawner.odds,
|
odds = spawner.odds,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -43,8 +43,8 @@ function getAvailableCartUpgrades(upgrades)
|
||||||
replace = {
|
replace = {
|
||||||
entityToModify = cart,
|
entityToModify = cart,
|
||||||
replacement = {
|
replacement = {
|
||||||
mass = cart.mass * 0.9
|
mass = cart.mass * 0.9,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
upgrades[#upgrades + 1] = {
|
upgrades[#upgrades + 1] = {
|
||||||
|
@ -52,8 +52,8 @@ function getAvailableCartUpgrades(upgrades)
|
||||||
replace = {
|
replace = {
|
||||||
entityToModify = cart.baseVelocity,
|
entityToModify = cart.baseVelocity,
|
||||||
replacement = {
|
replacement = {
|
||||||
x = cart.baseVelocity.x * 1.2
|
x = cart.baseVelocity.x * 1.2,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
upgrades[#upgrades + 1] = {
|
upgrades[#upgrades + 1] = {
|
||||||
|
@ -61,8 +61,8 @@ function getAvailableCartUpgrades(upgrades)
|
||||||
replace = {
|
replace = {
|
||||||
entityToModify = cart.baseVelocity,
|
entityToModify = cart.baseVelocity,
|
||||||
replacement = {
|
replacement = {
|
||||||
y = cart.baseVelocity.y * 1.2
|
y = cart.baseVelocity.y * 1.2,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue