From 476e0d54cb81d71c08f302776f00a203f609eabb Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sun, 9 Feb 2025 11:49:15 -0500 Subject: [PATCH] Start extracting ball.lua PseudoAnimator -> SimpleAnimator --- src/ball.lua | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.lua | 50 ++++++++++++----------------------------- src/utils.lua | 2 +- 3 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 src/ball.lua diff --git a/src/ball.lua b/src/ball.lua new file mode 100644 index 0000000..8115de6 --- /dev/null +++ b/src/ball.lua @@ -0,0 +1,62 @@ +-- selene: allow(unscoped_variables) +---@class Ball +---@field private gfx pd_graphics_lib +---@field x number +---@field y number +---@field z number +---@field size number +---@field heldBy Fielder | nil +---@field xAnimator SimpleAnimator +---@field yAnimator SimpleAnimator +---@field sizeAnimator SimpleAnimator +---@field floatAnimator SimpleAnimator +Ball = {} + +---@param g pd_graphics_lib +---@return Ball +function Ball.new(g) + return setmetatable({ + gfx = g, + x = C.Center.x --[[@as number]], + y = C.Center.y --[[@as number]], + z = 0, + size = C.SmallestBallRadius, + heldBy = nil --[[@type Runner | nil]], + + xAnimator = utils.staticAnimator(C.BallOffscreen), + yAnimator = utils.staticAnimator(C.BallOffscreen), + + -- TODO? Replace these with a ballAnimatorZ? + -- ...that might lose some of the magic of both. Compromise available? idk + sizeAnimator = utils.staticAnimator(C.SmallestBallRadius), + floatAnimator = g.animator.new(2000, -60, 0, utils.easingHill), + }, { __index = Ball }) +end + +--- Launches the ball from its current position to the given destination. +---@param destX number +---@param destY number +---@param easingFunc EasingFunc +---@param flyTimeMs number | nil +---@param floaty boolean | nil +---@param customBallScaler pd_animator | nil +function Ball:launch(destX, destY, easingFunc, flyTimeMs, floaty, customBallScaler) + self.heldBy = nil + + if not flyTimeMs then + flyTimeMs = utils.distanceBetween(self.x, self.y, destX, destY) * 5 + end + + if customBallScaler then + self.sizeAnimator = customBallScaler + else + -- TODO? Scale based on distance? + self.sizeAnimator = self.gfx.animator.new(flyTimeMs, 9, C.SmallestBallRadius, utils.easingHill) + end + self.yAnimator = self.gfx.animator.new(flyTimeMs, self.y, destY, easingFunc) + self.xAnimator = self.gfx.animator.new(flyTimeMs, self.x, destX, easingFunc) + if floaty then + self.floatAnimator:reset(flyTimeMs) + end +end + diff --git a/src/main.lua b/src/main.lua index 9368053..088e5c2 100644 --- a/src/main.lua +++ b/src/main.lua @@ -17,7 +17,14 @@ import 'CoreLibs/ui.lua' --- @alias EasingFunc fun(number, number, number, number): number ---- @alias LaunchBall fun(destX: number, destY: number, easingFunc: EasingFunc, flyTimeMs: number | nil, floaty: boolean | nil, customBallScaler: pd_animator | nil) +--- @alias LaunchBall fun( +--- destX: number, +--- destY: number, +--- easingFunc: EasingFunc, +--- flyTimeMs: number | nil, +--- floaty: boolean | nil, +--- customBallScaler: pd_animator | nil, +--- ) -- stylua: ignore start import 'utils.lua' @@ -26,6 +33,7 @@ import 'assets.lua' import 'action-queue.lua' import 'announcer.lua' +import 'ball.lua' import 'baserunning.lua' import 'dbg.lua' import 'fielding.lua' @@ -38,30 +46,16 @@ import 'draw/fielder.lua' -- selene: allow(shadowing) local gfx , C = playdate.graphics, C -local announcer = Announcer:new() +local announcer = Announcer.new() local baserunning = Baserunning.new(announcer) local fielding = Fielding.new() ----@alias PseudoAnimator { currentValue: fun(self): number; reset: fun(self, durationMs: number | nil) } ----@alias Pitch { x: PseudoAnimator, y: PseudoAnimator, z: PseudoAnimator | nil } +---@alias SimpleAnimator { currentValue: fun(self): number; reset: fun(self, durationMs: number | nil) } +---@alias Pitch { x: SimpleAnimator, y: SimpleAnimator, z: SimpleAnimator | nil } local deltaSeconds = 0 -local ball = { - x = C.Center.x --[[@as number]], - y = C.Center.y --[[@as number]], - z = 0, - size = C.SmallestBallRadius, - heldBy = nil --[[@type Runner | nil]], - - xAnimator = utils.staticAnimator(C.BallOffscreen), - yAnimator = utils.staticAnimator(C.BallOffscreen), - - -- TODO? Replace these with a ballAnimatorZ? - -- ...that might lose some of the magic of both. Compromise available? idk - sizeAnimator = utils.staticAnimator(C.SmallestBallRadius), - floatAnimator = gfx.animator.new(2000, -60, 0, utils.easingHill), -} +local ball = Ball.new(gfx) ---@alias Team { score: number, benchPosition: XyPair } @@ -152,24 +146,8 @@ end ---@param floaty boolean | nil ---@param customBallScaler pd_animator | nil local function launchBall(destX, destY, easingFunc, flyTimeMs, floaty, customBallScaler) - ball.heldBy = nil throwMeter = 0 - - if not flyTimeMs then - flyTimeMs = utils.distanceBetween(ball.x, ball.y, destX, destY) * 5 - end - - if customBallScaler then - ball.sizeAnimator = customBallScaler - else - -- TODO? Scale based on distance? - ball.sizeAnimator = gfx.animator.new(flyTimeMs, 9, C.SmallestBallRadius, utils.easingHill) - end - ball.yAnimator = gfx.animator.new(flyTimeMs, ball.y, destY, easingFunc) - ball.xAnimator = gfx.animator.new(flyTimeMs, ball.x, destX, easingFunc) - if floaty then - ball.floatAnimator:reset(flyTimeMs) - end + ball:launch(destX, destY, easingFunc, flyTimeMs, floaty, customBallScaler) end ---@param pitchFlyTimeMs number | nil diff --git a/src/utils.lua b/src/utils.lua index 900730a..8e9a1f7 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -25,7 +25,7 @@ end --- Build an "animator" whose `:currentValue()` always returns the given value. --- Essentially an "empty object" pattern for initial object positions. ---@param value number ----@return PseudoAnimator +---@return SimpleAnimator function utils.staticAnimator(value) return { currentValue = function(_)