diff --git a/src/cart.lua b/src/cart.lua index 74c8345..9f9fbfe 100644 --- a/src/cart.lua +++ b/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 } diff --git a/src/main.lua b/src/main.lua index e6c91fc..63e4706 100644 --- a/src/main.lua +++ b/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() diff --git a/src/systems/filter-types.lua b/src/systems/filter-types.lua index ca2dad3..6709af2 100644 --- a/src/systems/filter-types.lua +++ b/src/systems/filter-types.lua @@ -7,12 +7,13 @@ local SOME_TABLE = {} ---@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, diff --git a/src/systems/filter-types.lua2p b/src/systems/filter-types.lua2p index a436829..d2e59d5 100644 --- a/src/systems/filter-types.lua2p +++ b/src/systems/filter-types.lua2p @@ -64,7 +64,8 @@ local SOME_TABLE = {} 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 }", diff --git a/src/systems/input.lua b/src/systems/input.lua index bb4ea1c..aa49d75 100644 --- a/src/systems/input.lua +++ b/src/systems/input.lua @@ -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 diff --git a/src/systems/menu.lua b/src/systems/menu.lua index 3ac9f29..eebfa97 100644 --- a/src/systems/menu.lua +++ b/src/systems/menu.lua @@ -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 diff --git a/src/systems/rounds.lua b/src/systems/rounds.lua index f3276e1..8e69af6 100644 --- a/src/systems/rounds.lua +++ b/src/systems/rounds.lua @@ -96,7 +96,7 @@ roundSystem = filteredSystem( y = y - 50 local menuEntity = { menuItems = {}, - canReceiveInput = T.marker, + canReceiveButtons = T.marker, } local upgradeBelow local i = #collectedEntities.entities diff --git a/src/tiny-tools.lua b/src/tiny-tools.lua index 26d6917..45b70fe 100644 --- a/src/tiny-tools.lua +++ b/src/tiny-tools.lua @@ -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