Split crank and button input states.
Add crank-powered cart-launch 😎
This commit is contained in:
parent
03e5ce69cf
commit
edeed9f4d0
28
src/cart.lua
28
src/cart.lua
|
@ -2,19 +2,35 @@ Cart = {}
|
|||
|
||||
local sizeX, sizeY = CartSprite:getSize()
|
||||
local size = { x = sizeX, y = sizeY * 0.75 }
|
||||
local secOver90 = 0
|
||||
|
||||
filteredSystem("launchedByCrank", { launchedByCrank = T.marker, crankState = T.CrankState, baseVelocity = T.XyPair }, function(e, dt, system)
|
||||
local change = math.abs(e.crankState.changeInLastHalfSecond)
|
||||
if change > 90 then
|
||||
secOver90 = secOver90 + dt
|
||||
end
|
||||
|
||||
if secOver90 > 0.05 then
|
||||
secOver90 = 0
|
||||
local launchPower = change - 40
|
||||
print("Launch power: " .. launchPower)
|
||||
e.launchedByCrank = nil
|
||||
e.crankState = nil
|
||||
e.velocity = { x = launchPower * e.baseVelocity.x, y = launchPower * e.baseVelocity.y }
|
||||
system.world:addEntity(e)
|
||||
end
|
||||
end)
|
||||
|
||||
cartSystem = filteredSystem("cart", { isCart = T.marker })
|
||||
|
||||
function Cart.reset(o)
|
||||
o.launchedByCrank = T.marker
|
||||
o.isCart = T.marker
|
||||
o.position = {
|
||||
x = 20,
|
||||
y = 50,
|
||||
}
|
||||
o.velocity = {
|
||||
x = o.baseVelocity.x + (100 * math.random()),
|
||||
y = o.baseVelocity.y * math.random(),
|
||||
}
|
||||
o.velocity = nil
|
||||
o.size = size
|
||||
o.canBeBounced = {
|
||||
flat = { x = 0, y = 0 },
|
||||
|
@ -52,8 +68,8 @@ function Cart.new()
|
|||
return setmetatable(
|
||||
Cart.reset({
|
||||
baseVelocity = {
|
||||
x = 300,
|
||||
y = -170,
|
||||
x = 2,
|
||||
y = -1,
|
||||
},
|
||||
}),
|
||||
{ __index = Cart }
|
||||
|
|
28
src/main.lua
28
src/main.lua
|
@ -70,7 +70,8 @@ world:addEntity(floor)
|
|||
|
||||
local scenarios = {
|
||||
default = function()
|
||||
world:addEntity(Cart.new())
|
||||
local cart = Cart.new()
|
||||
world:addEntity(cart)
|
||||
end,
|
||||
manyCollectables = function()
|
||||
local cart = Cart.new()
|
||||
|
@ -86,7 +87,7 @@ local scenarios = {
|
|||
end,
|
||||
}
|
||||
|
||||
scenarios.manyCollectables()
|
||||
scenarios.default()
|
||||
|
||||
addAllSpawners(world)
|
||||
|
||||
|
@ -97,29 +98,6 @@ playdate.setAutoLockDisabled(true)
|
|||
|
||||
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()
|
||||
local deltaSeconds = playdate.getElapsedTime()
|
||||
playdate.resetElapsedTime()
|
||||
|
|
|
@ -7,12 +7,13 @@ local SOME_TABLE <const> = {}
|
|||
|
||||
---@alias AnyComponent any
|
||||
---@alias BitMask number
|
||||
---@alias ButtonState { receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }
|
||||
---@alias CanBeBounced { flat: XyPair, mult = XyPair }
|
||||
---@alias CanSpawn { entityToSpawn: Entity }
|
||||
---@alias Collision { collisionBetween: Entity[] }
|
||||
---@alias CrankState { crankChange: number, changeInLastHalfSecond: number }
|
||||
---@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: table }
|
||||
---@alias RoundStateAction "end" | "start"
|
||||
---@alias Selectable { additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }
|
||||
|
@ -45,6 +46,9 @@ T = {
|
|||
---@type BitMask
|
||||
BitMask = 0,
|
||||
|
||||
---@type ButtonState
|
||||
ButtonState = SOME_TABLE,
|
||||
|
||||
---@type CanBeBounced
|
||||
CanBeBounced = SOME_TABLE,
|
||||
|
||||
|
@ -54,15 +58,15 @@ T = {
|
|||
---@type Collision
|
||||
Collision = SOME_TABLE,
|
||||
|
||||
---@type CrankState
|
||||
CrankState = SOME_TABLE,
|
||||
|
||||
---@type Entity
|
||||
Entity = SOME_TABLE,
|
||||
|
||||
---@type InRelations
|
||||
InRelations = SOME_TABLE,
|
||||
|
||||
---@type InputState
|
||||
InputState = SOME_TABLE,
|
||||
|
||||
---@type ReplaceRelation
|
||||
ReplaceRelation = SOME_TABLE,
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@ local SOME_TABLE <const> = {}
|
|||
CanSpawn = "{ entityToSpawn: Entity }",
|
||||
InRelations = "Entity[]",
|
||||
CanBeBounced = "{ flat: XyPair, mult = XyPair }",
|
||||
InputState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }",
|
||||
ButtonState = "{ receivedInputThisFrame: boolean, aJustPressed: boolean, bJustPressed: boolean, upJustPressed: boolean, downJustPressed: boolean, leftJustPressed: boolean, rightJustPressed: boolean }",
|
||||
CrankState = "{ crankChange: number, changeInLastHalfSecond: number }",
|
||||
|
||||
ReplaceRelation = "{ entityToModify: Entity, replacement: table }",
|
||||
Selectable = "{ additions: Entity[] | nil, replacements: ReplaceRelation[] | nil, highlighted: boolean, navigateDown: Selectable | nil, navigateUp: Selectable | nil }",
|
||||
|
|
|
@ -1,25 +1,66 @@
|
|||
local buttonJustPressed = playdate.buttonJustPressed
|
||||
|
||||
---@type InputState
|
||||
local inputState = {}
|
||||
---@type ButtonState
|
||||
local buttonState = {}
|
||||
|
||||
inputSystem = filteredSystem("input", { canReceiveInput = T.marker }, function(e, _, system)
|
||||
e.inputState = inputState
|
||||
buttonInputSystem = filteredSystem("buttonInput", { canReceiveButtons = T.marker }, function(e, _, system)
|
||||
e.buttonState = buttonState
|
||||
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)
|
||||
function buttonInputSystem:preProcess()
|
||||
if #self.entities == 0 then
|
||||
return
|
||||
end
|
||||
buttonState.upJustPressed = buttonJustPressed(playdate.kButtonUp)
|
||||
buttonState.downJustPressed = buttonJustPressed(playdate.kButtonDown)
|
||||
buttonState.rightJustPressed = buttonJustPressed(playdate.kButtonRight)
|
||||
buttonState.leftJustPressed = buttonJustPressed(playdate.kButtonLeft)
|
||||
buttonState.aJustPressed = buttonJustPressed(playdate.kButtonA)
|
||||
buttonState.bJustPressed = buttonJustPressed(playdate.kButtonB)
|
||||
|
||||
inputState.receivedInputThisFrame = inputState.upJustPressed
|
||||
or inputState.downJustPressed
|
||||
or inputState.rightJustPressed
|
||||
or inputState.leftJustPressed
|
||||
or inputState.aJustPressed
|
||||
or inputState.bJustPressed
|
||||
buttonState.receivedInputThisFrame = buttonState.upJustPressed
|
||||
or buttonState.downJustPressed
|
||||
or buttonState.rightJustPressed
|
||||
or buttonState.leftJustPressed
|
||||
or buttonState.aJustPressed
|
||||
or buttonState.bJustPressed
|
||||
end
|
||||
|
||||
local crankState = {}
|
||||
|
||||
crankInputSystem = filteredSystem(
|
||||
"crankInput",
|
||||
tiny.requireAny("canReceiveCrank", "launchedByCrank"),
|
||||
function(e, _, system)
|
||||
e.crankState = crankState
|
||||
system.world:addEntity(e)
|
||||
end
|
||||
)
|
||||
|
||||
crankHistory = filteredSystem("crankHistory", { crankChange = T.number, msOccurred = T.number })
|
||||
|
||||
function crankInputSystem:preProcess()
|
||||
if #self.entities == 0 then
|
||||
return
|
||||
end
|
||||
local currentMs = playdate.getCurrentTimeMilliseconds()
|
||||
local crankChange = playdate.getCrankChange()
|
||||
|
||||
self.world:addEntity({
|
||||
crankChange = crankChange,
|
||||
msOccurred = currentMs,
|
||||
})
|
||||
|
||||
local changeInLastHalfSecond = 0
|
||||
for _, v in pairs(crankHistory.entities) do
|
||||
if currentMs - v.msOccurred > 500 then
|
||||
self.world:removeEntity(v)
|
||||
else
|
||||
changeInLastHalfSecond = changeInLastHalfSecond + v.crankChange
|
||||
end
|
||||
end
|
||||
|
||||
crankState.crankChange = crankChange
|
||||
crankState.changeInLastHalfSecond = changeInLastHalfSecond
|
||||
end
|
||||
|
|
|
@ -9,11 +9,11 @@ end
|
|||
|
||||
menuController = filteredSystem(
|
||||
"menuController",
|
||||
{ menuItems = Arr(T.Selectable), inputState = T.InputState },
|
||||
{ menuItems = Arr(T.Selectable), buttonState = T.ButtonState },
|
||||
function(e, _, system)
|
||||
for _, menuItem in pairs(e.menuItems) do
|
||||
if menuItem.highlighted then
|
||||
if e.inputState.aJustPressed then
|
||||
if e.buttonState.aJustPressed then
|
||||
-- Prepare to remove the menu and all menu items
|
||||
system.world:removeEntity(e)
|
||||
for _, item in pairs(e.menuItems) do
|
||||
|
@ -35,13 +35,13 @@ menuController = filteredSystem(
|
|||
end
|
||||
end
|
||||
|
||||
if e.inputState.downJustPressed and menuItem.navigateDown then
|
||||
if e.buttonState.downJustPressed and menuItem.navigateDown then
|
||||
menuItem.highlighted = false
|
||||
menuItem.navigateDown.highlighted = true
|
||||
return
|
||||
end
|
||||
|
||||
if e.inputState.upJustPressed and menuItem.navigateUp then
|
||||
if e.buttonState.upJustPressed and menuItem.navigateUp then
|
||||
menuItem.highlighted = false
|
||||
menuItem.navigateUp.highlighted = true
|
||||
return
|
||||
|
|
|
@ -96,7 +96,7 @@ roundSystem = filteredSystem(
|
|||
y = y - 50
|
||||
local menuEntity = {
|
||||
menuItems = {},
|
||||
canReceiveInput = T.marker,
|
||||
canReceiveButtons = T.marker,
|
||||
}
|
||||
local upgradeBelow
|
||||
local i = #collectedEntities.entities
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
---@generic T
|
||||
---@param shape T
|
||||
---@param shape T | fun()
|
||||
---@param process fun(entity: T, dt: number, system: System)
|
||||
---@return System | { entities: T[] }
|
||||
function filteredSystem(name, shape, process)
|
||||
assert(type(name) == "string")
|
||||
assert(type(shape) == "table")
|
||||
assert(type(shape) == "table" or type(shape) == "function")
|
||||
assert(process == nil or type(process) == "function")
|
||||
|
||||
local system = tiny.processingSystem()
|
||||
system.name = name
|
||||
local keys = {}
|
||||
for key, value in pairs(shape) do
|
||||
local isTable = type(value) == "table"
|
||||
local isMaybe = isTable and value.maybe ~= nil
|
||||
if type(shape) == "table" then
|
||||
local keys = {}
|
||||
for key, value in pairs(shape) do
|
||||
local isTable = type(value) == "table"
|
||||
local isMaybe = isTable and value.maybe ~= nil
|
||||
|
||||
if not isMaybe then
|
||||
-- ^ Don't require any Maybe types
|
||||
keys[#keys + 1] = key
|
||||
if not isMaybe then
|
||||
-- ^ Don't require any Maybe types
|
||||
keys[#keys + 1] = key
|
||||
end
|
||||
end
|
||||
system.filter = tiny.requireAll(table.unpack(keys))
|
||||
elseif type(shape) == "function" then
|
||||
system.filter = shape
|
||||
end
|
||||
system.filter = tiny.requireAll(table.unpack(keys))
|
||||
if not process then
|
||||
return world:addSystem(system)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue