-- stylua: ignore start import 'CoreLibs/animation.lua' import 'CoreLibs/graphics.lua' -- stylua: ignore end -- selene: allow(unscoped_variables) utils = {} function utils.easingHill(t, b, c, d) c = c + 0.0 -- convert to float to prevent integer overflow t = t / d t = ((t * 2) - 1) t = t * t return (c * t) + b end -- Useful for quick print-the-value-in-place debugging. -- selene: allow(unused_variable) function utils.label(value, name) if type(value) == "table" then print(name .. ":") printTable(value) else print(name .. ": " .. value) end return value end ---@param x number ---@param y number ---@return XYPair function utils.xy(x, y) return { x = x, y = y, } end --- Returns the normalized vector as two values, plus the distance between the given points. ---@param x1 number ---@param y1 number ---@param x2 number ---@param y2 number ---@return number x, number y, number distance function utils.normalizeVector(x1, y1, x2, y2) local distance, a, b = utils.distanceBetween(x1, y1, x2, y2) return a / distance, b / distance, distance end ---@generic T ---@param array T[] ---@param condition fun(T): boolean ---@return T[] function utils.filter(array, condition) local newArray = {} for _, element in pairs(array) do if condition(element) then newArray[#newArray + 1] = element end end return newArray end ---@return number distance, number x, number y function utils.distanceBetween(x1, y1, x2, y2) local a = x1 - x2 local b = y1 - y2 return math.sqrt((a * a) + (b * b)), a, b end ---@return number distance, number x, number y function utils.distanceBetweenZ(x1, y1, z1, x2, y2, z2) local a = x1 - x2 local b = y1 - y2 local c = z1 - z2 return math.sqrt((a * a) + (b * b) + (c * c)), a, b end --- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound --- @return boolean function utils.pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound) -- This check currently assumes right-handedness. -- I.e. it assumes the ball is to the right of batBaseX if pointX < lineX1 or pointX > lineX2 or pointY > bottomBound then return false end local m = (lineY2 - lineY1) / (lineX2 - lineX1) -- y = mx + b -- b = y1 - (m * x1) local b = lineY1 - (m * lineX1) local yOnLine = (m * pointX) + b local yP = pointY local yDelta = yOnLine - yP return yDelta <= 0 end --- Returns the nearest position object from the given point, as well as its distance from that point ---@generic T : {x: number, y: number | nil} ---@param array T[] ---@param x number ---@param y number ---@return T,number|nil function utils.getNearestOf(array, x, y, extraCondition) local nearest, nearestDistance = nil, nil for _, element in pairs(array) do if not extraCondition or extraCondition(element) then if nearest == nil then nearest = element nearestDistance = utils.distanceBetween(element.x, element.y, x, y) else local distance = utils.distanceBetween(element.x, element.y, x, y) if distance < nearestDistance then nearest = element nearestDistance = distance end end end end return nearest, nearestDistance end ---@alias Cache { get: fun(key: `Key`): `Value` } if not playdate then return utils end