BatterUp/src/utils.lua

131 lines
3.5 KiB
Lua

-- 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