Switch to spaces.
This commit is contained in:
parent
44ba30ee97
commit
9df836e0bf
4
Makefile
4
Makefile
|
@ -4,8 +4,8 @@ all:
|
||||||
pdc src BatterUp.pdx
|
pdc src BatterUp.pdx
|
||||||
|
|
||||||
check:
|
check:
|
||||||
stylua -c src/
|
stylua -c --indent-type Spaces src/
|
||||||
cat __stub.ext.lua <(sed 's/^function/-- selene: allow(unused_variable)\nfunction/' ${PLAYDATE_SDK_PATH}/CoreLibs/__types.lua) ${SOURCE_FILES} | grep -v '^import' | sed 's/<const>//g' | selene -
|
cat __stub.ext.lua <(sed 's/^function/-- selene: allow(unused_variable)\nfunction/' ${PLAYDATE_SDK_PATH}/CoreLibs/__types.lua) ${SOURCE_FILES} | grep -v '^import' | sed 's/<const>//g' | selene -
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
stylua src/
|
stylua --indent-type Spaces src/
|
||||||
|
|
|
@ -3,60 +3,60 @@ local AnnouncementTransitionMs <const> = 300
|
||||||
local AnnouncerMarginX <const> = 26
|
local AnnouncerMarginX <const> = 26
|
||||||
|
|
||||||
local AnnouncerAnimatorInY <const> =
|
local AnnouncerAnimatorInY <const> =
|
||||||
playdate.graphics.animator.new(AnnouncementTransitionMs, -70, 0, playdate.easingFunctions.outBounce)
|
playdate.graphics.animator.new(AnnouncementTransitionMs, -70, 0, playdate.easingFunctions.outBounce)
|
||||||
local AnnouncerAnimatorOutY <const> =
|
local AnnouncerAnimatorOutY <const> =
|
||||||
playdate.graphics.animator.new(AnnouncementTransitionMs, 0, -70, playdate.easingFunctions.outQuint)
|
playdate.graphics.animator.new(AnnouncementTransitionMs, 0, -70, playdate.easingFunctions.outQuint)
|
||||||
|
|
||||||
-- selene: allow(unscoped_variables)
|
-- selene: allow(unscoped_variables)
|
||||||
announcer = {
|
announcer = {
|
||||||
textQueue = {},
|
textQueue = {},
|
||||||
animatorY = AnnouncerAnimatorInY,
|
animatorY = AnnouncerAnimatorInY,
|
||||||
}
|
}
|
||||||
|
|
||||||
local DurationMs <const> = 3000
|
local DurationMs <const> = 3000
|
||||||
|
|
||||||
function announcer.popIn(self)
|
function announcer.popIn(self)
|
||||||
self.animatorY = AnnouncerAnimatorInY
|
self.animatorY = AnnouncerAnimatorInY
|
||||||
self.animatorY:reset()
|
self.animatorY:reset()
|
||||||
|
|
||||||
playdate.timer.new(DurationMs, function()
|
playdate.timer.new(DurationMs, function()
|
||||||
self.animatorY = AnnouncerAnimatorOutY
|
self.animatorY = AnnouncerAnimatorOutY
|
||||||
self.animatorY:reset()
|
self.animatorY:reset()
|
||||||
-- If this popIn() call was inside a timer, successive messages would be
|
-- If this popIn() call was inside a timer, successive messages would be
|
||||||
-- allowed to transition out. However, the Out animation, shortly followed by
|
-- allowed to transition out. However, the Out animation, shortly followed by
|
||||||
-- a new message popping in, is actually *more* jarring than the interrupt.
|
-- a new message popping in, is actually *more* jarring than the interrupt.
|
||||||
if #self.textQueue ~= 1 then
|
if #self.textQueue ~= 1 then
|
||||||
self:popIn()
|
self:popIn()
|
||||||
table.remove(self.textQueue, 1)
|
table.remove(self.textQueue, 1)
|
||||||
else
|
else
|
||||||
playdate.timer.new(AnnouncementTransitionMs, function()
|
playdate.timer.new(AnnouncementTransitionMs, function()
|
||||||
table.remove(self.textQueue, 1)
|
table.remove(self.textQueue, 1)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function announcer.say(self, text)
|
function announcer.say(self, text)
|
||||||
self.textQueue[#self.textQueue + 1] = text
|
self.textQueue[#self.textQueue + 1] = text
|
||||||
if #self.textQueue == 1 then
|
if #self.textQueue == 1 then
|
||||||
self:popIn()
|
self:popIn()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function announcer.draw(self, x, y)
|
function announcer.draw(self, x, y)
|
||||||
if #self.textQueue == 0 then
|
if #self.textQueue == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
x = x - 5 -- Infield center is slightly offset from screen center
|
x = x - 5 -- Infield center is slightly offset from screen center
|
||||||
|
|
||||||
local gfx = playdate.graphics
|
local gfx = playdate.graphics
|
||||||
local originalDrawMode = gfx.getImageDrawMode()
|
local originalDrawMode = gfx.getImageDrawMode()
|
||||||
local width = math.max(150, (AnnouncerMarginX * 2) + AnnouncementFont:getTextWidth(self.textQueue[1]))
|
local width = math.max(150, (AnnouncerMarginX * 2) + AnnouncementFont:getTextWidth(self.textQueue[1]))
|
||||||
local animY = self.animatorY:currentValue()
|
local animY = self.animatorY:currentValue()
|
||||||
|
|
||||||
gfx.setColor(gfx.kColorBlack)
|
gfx.setColor(gfx.kColorBlack)
|
||||||
gfx.fillRect(x - (width / 2), y + animY, width, 50)
|
gfx.fillRect(x - (width / 2), y + animY, width, 50)
|
||||||
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
||||||
AnnouncementFont:drawTextAligned(self.textQueue[1], x, y + 10 + animY, kTextAlignment.center)
|
AnnouncementFont:drawTextAligned(self.textQueue[1], x, y + 10 + animY, kTextAlignment.center)
|
||||||
gfx.setImageDrawMode(originalDrawMode)
|
gfx.setImageDrawMode(originalDrawMode)
|
||||||
end
|
end
|
||||||
|
|
216
src/ecs.lua
216
src/ecs.lua
|
@ -9,46 +9,46 @@ local systems <const> = {}
|
||||||
|
|
||||||
-- TODO: Add entity to any existing systems
|
-- TODO: Add entity to any existing systems
|
||||||
function ecs.addEntity(entity)
|
function ecs.addEntity(entity)
|
||||||
allEntities[entity] = true
|
allEntities[entity] = true
|
||||||
for _, system in pairs(systems) do
|
for _, system in pairs(systems) do
|
||||||
if entityMatchesShapes(entity, system.shapes) then
|
if entityMatchesShapes(entity, system.shapes) then
|
||||||
system.entityCache[entity] = true
|
system.entityCache[entity] = true
|
||||||
else
|
else
|
||||||
system.entityCache[entity] = nil
|
system.entityCache[entity] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ecs.removeEntity(entity)
|
function ecs.removeEntity(entity)
|
||||||
allEntities[entity] = nil
|
allEntities[entity] = nil
|
||||||
for _, system in pairs(systems) do
|
for _, system in pairs(systems) do
|
||||||
system.entityCache[entity] = nil
|
system.entityCache[entity] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local Placeholder = {}
|
local Placeholder = {}
|
||||||
---@generic T
|
---@generic T
|
||||||
---@return T
|
---@return T
|
||||||
function ecs.field()
|
function ecs.field()
|
||||||
return Placeholder
|
return Placeholder
|
||||||
end
|
end
|
||||||
|
|
||||||
function allKeysIncluded(entity, filter)
|
function allKeysIncluded(entity, filter)
|
||||||
for k, _ in pairs(filter) do
|
for k, _ in pairs(filter) do
|
||||||
if not entity[k] then
|
if not entity[k] then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function entityMatchesShapes(entity, shapes)
|
function entityMatchesShapes(entity, shapes)
|
||||||
for _, shape in pairs(shapes) do
|
for _, shape in pairs(shapes) do
|
||||||
if not allKeysIncluded(entity, shape) then
|
if not allKeysIncluded(entity, shape) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
@ -61,66 +61,66 @@ end
|
||||||
---@param wShape W?
|
---@param wShape W?
|
||||||
---@return fun(callback: fun(componentT: T, componentU: U, componentV: V, componentW: W))
|
---@return fun(callback: fun(componentT: T, componentU: U, componentV: V, componentW: W))
|
||||||
function ecs.entitiesHavingShapes(tShape, uShape, vShape, wShape)
|
function ecs.entitiesHavingShapes(tShape, uShape, vShape, wShape)
|
||||||
return function() end
|
return function() end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Print contents of `tbl`, with indentation.
|
-- Print contents of `tbl`, with indentation.
|
||||||
-- `indent` sets the initial level of indentation.
|
-- `indent` sets the initial level of indentation.
|
||||||
function tprint(tbl, indent)
|
function tprint(tbl, indent)
|
||||||
if not indent then
|
if not indent then
|
||||||
indent = 0
|
indent = 0
|
||||||
end
|
end
|
||||||
for k, v in pairs(tbl) do
|
for k, v in pairs(tbl) do
|
||||||
formatting = string.rep(" ", indent) .. k .. ": "
|
formatting = string.rep(" ", indent) .. k .. ": "
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
print(formatting)
|
print(formatting)
|
||||||
tprint(v, indent + 1)
|
tprint(v, indent + 1)
|
||||||
elseif type(v) == "boolean" then
|
elseif type(v) == "boolean" then
|
||||||
print(formatting .. tostring(v))
|
print(formatting .. tostring(v))
|
||||||
else
|
else
|
||||||
print(formatting .. v)
|
print(formatting .. v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function addSystem(callback, keys, shapes)
|
function addSystem(callback, keys, shapes)
|
||||||
systems[#systems + 1] = {
|
systems[#systems + 1] = {
|
||||||
callback = callback,
|
callback = callback,
|
||||||
keys = keys,
|
keys = keys,
|
||||||
shapes = shapes,
|
shapes = shapes,
|
||||||
entityCache = nil,
|
entityCache = nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return boolean
|
---@return boolean
|
||||||
function is(entity, shape)
|
function is(entity, shape)
|
||||||
return allKeysIncluded(entity, shape)
|
return allKeysIncluded(entity, shape)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param deltaSeconds number
|
---@param deltaSeconds number
|
||||||
function ecs.update(deltaSeconds)
|
function ecs.update(deltaSeconds)
|
||||||
for _, system in pairs(systems) do
|
for _, system in pairs(systems) do
|
||||||
if not system.entityCache then
|
if not system.entityCache then
|
||||||
system.entityCache = {}
|
system.entityCache = {}
|
||||||
for entity, _ in pairs(allEntities) do
|
for entity, _ in pairs(allEntities) do
|
||||||
if entityMatchesShapes(entity, system.shapes) then
|
if entityMatchesShapes(entity, system.shapes) then
|
||||||
system.entityCache[entity] = true
|
system.entityCache[entity] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local keys = system.keys
|
local keys = system.keys
|
||||||
for entity, _ in pairs(system.entityCache) do
|
for entity, _ in pairs(system.entityCache) do
|
||||||
system.callback(
|
system.callback(
|
||||||
deltaSeconds,
|
deltaSeconds,
|
||||||
entity,
|
entity,
|
||||||
entity[keys[1]],
|
entity[keys[1]],
|
||||||
entity[keys[2]],
|
entity[keys[2]],
|
||||||
entity[keys[3]],
|
entity[keys[3]],
|
||||||
entity[keys[4]],
|
entity[keys[4]],
|
||||||
entity
|
entity
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a function that accepts a callback. This callback will receive one argument for each Shape provided.
|
--- Returns a function that accepts a callback. This callback will receive one argument for each Shape provided.
|
||||||
|
@ -139,26 +139,26 @@ end
|
||||||
---@param wShape { [WKey]: W } | fun(entity: any, componentT: T, componentU: U, componentV: V, any) | nil
|
---@param wShape { [WKey]: W } | fun(entity: any, componentT: T, componentU: U, componentV: V, any) | nil
|
||||||
---@param finalFunc fun(entity: any, componentT: T, componentU: U, componentV: V, componentW: W, any) | nil
|
---@param finalFunc fun(entity: any, componentT: T, componentU: U, componentV: V, componentW: W, any) | nil
|
||||||
function ecs.forEntitiesWith(tShape, uShape, vShape, wShape, finalFunc)
|
function ecs.forEntitiesWith(tShape, uShape, vShape, wShape, finalFunc)
|
||||||
local maybeShapes = { tShape, uShape, vShape, wShape, finalFunc }
|
local maybeShapes = { tShape, uShape, vShape, wShape, finalFunc }
|
||||||
local shapes = {}
|
local shapes = {}
|
||||||
local callback
|
local callback
|
||||||
|
|
||||||
for _, maybeShape in pairs(maybeShapes) do
|
for _, maybeShape in pairs(maybeShapes) do
|
||||||
if type(maybeShape) == "table" then
|
if type(maybeShape) == "table" then
|
||||||
shapes[#shapes + 1] = maybeShape
|
shapes[#shapes + 1] = maybeShape
|
||||||
elseif type(maybeShape) == "function" then
|
elseif type(maybeShape) == "function" then
|
||||||
callback = maybeShape
|
callback = maybeShape
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local keys = {}
|
local keys = {}
|
||||||
for _, shape in pairs(shapes) do
|
for _, shape in pairs(shapes) do
|
||||||
for key, _ in pairs(shape) do
|
for key, _ in pairs(shape) do
|
||||||
keys[#keys + 1] = key
|
keys[#keys + 1] = key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
addSystem(callback, keys, shapes)
|
addSystem(callback, keys, shapes)
|
||||||
end
|
end
|
||||||
|
|
||||||
local f = ecs.field()
|
local f = ecs.field()
|
||||||
|
@ -168,15 +168,15 @@ local Target = { target = XYPair }
|
||||||
local Velocity = { velocity = XYPair }
|
local Velocity = { velocity = XYPair }
|
||||||
|
|
||||||
function ecs.overlayOnto(entity, value)
|
function ecs.overlayOnto(entity, value)
|
||||||
for key, v in pairs(value) do
|
for key, v in pairs(value) do
|
||||||
entity[key] = v
|
entity[key] = v
|
||||||
end
|
end
|
||||||
ecs.addEntity(entity)
|
ecs.addEntity(entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
local data = {
|
local data = {
|
||||||
position = { x = 0, y = 0 },
|
position = { x = 0, y = 0 },
|
||||||
velocity = { x = 1, y = 2 },
|
velocity = { x = 1, y = 2 },
|
||||||
}
|
}
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
@ -184,7 +184,7 @@ local data = {
|
||||||
---@param entity unknown
|
---@param entity unknown
|
||||||
---@return T
|
---@return T
|
||||||
function ecs.get(shape, entity)
|
function ecs.get(shape, entity)
|
||||||
return entity
|
return entity
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
@ -192,29 +192,29 @@ end
|
||||||
---@param shape `T`
|
---@param shape `T`
|
||||||
---@param value `T`
|
---@param value `T`
|
||||||
function ecs.set(entity, shape, value)
|
function ecs.set(entity, shape, value)
|
||||||
for key, v in pairs(shape) do
|
for key, v in pairs(shape) do
|
||||||
entity[key] = value[v]
|
entity[key] = value[v]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ecs.addEntity(data)
|
ecs.addEntity(data)
|
||||||
|
|
||||||
ecs.forEntitiesWith(Position, Velocity, function(delta, e, pos, vel)
|
ecs.forEntitiesWith(Position, Velocity, function(delta, e, pos, vel)
|
||||||
pos.x = pos.x + (delta * vel.x)
|
pos.x = pos.x + (delta * vel.x)
|
||||||
pos.y = pos.y + (delta * vel.y)
|
pos.y = pos.y + (delta * vel.y)
|
||||||
print("position")
|
print("position")
|
||||||
tprint(pos, 1)
|
tprint(pos, 1)
|
||||||
ecs.set(Target, e, {
|
ecs.set(Target, e, {
|
||||||
--target = { x = 10, y = 10}
|
--target = { x = 10, y = 10}
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
ecs.forEntitiesWith(Target, function(delta, e, pos, vel)
|
ecs.forEntitiesWith(Target, function(delta, e, pos, vel)
|
||||||
pos.x = pos.x + (delta * vel.x)
|
pos.x = pos.x + (delta * vel.x)
|
||||||
pos.y = pos.y + (delta * vel.y)
|
pos.y = pos.y + (delta * vel.y)
|
||||||
print("position")
|
print("position")
|
||||||
tprint(pos, 1)
|
tprint(pos, 1)
|
||||||
ecs.set(e, Target, "hallo")
|
ecs.set(e, Target, "hallo")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
ecs.update(1)
|
ecs.update(1)
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
--- XOX
|
--- XOX
|
||||||
--- Where each character is the size of the screen, and 'O' is the default view.
|
--- Where each character is the size of the screen, and 'O' is the default view.
|
||||||
function getDrawOffset(screenW, screenH, ballX, ballY)
|
function getDrawOffset(screenW, screenH, ballX, ballY)
|
||||||
local offsetX, offsetY
|
local offsetX, offsetY
|
||||||
if ballY > screenH then
|
if ballY > screenH then
|
||||||
return 0, 0
|
return 0, 0
|
||||||
end
|
end
|
||||||
offsetY = math.max(0, -1 * ballY)
|
offsetY = math.max(0, -1 * ballY)
|
||||||
|
|
||||||
if ballX > 0 and ballX < screenW then
|
if ballX > 0 and ballX < screenW then
|
||||||
offsetX = 0
|
offsetX = 0
|
||||||
elseif ballX < 0 then
|
elseif ballX < 0 then
|
||||||
offsetX = math.max(-1 * screenW, ballX * -1)
|
offsetX = math.max(-1 * screenW, ballX * -1)
|
||||||
elseif ballX > screenW then
|
elseif ballX > screenW then
|
||||||
offsetX = math.min(screenW * 2, (ballX * -1) + screenW)
|
offsetX = math.min(screenW * 2, (ballX * -1) + screenW)
|
||||||
end
|
end
|
||||||
|
|
||||||
return offsetX * 1.3, offsetY * 1.5
|
return offsetX * 1.3, offsetY * 1.5
|
||||||
end
|
end
|
||||||
|
|
||||||
-- selene: allow(unscoped_variables)
|
-- selene: allow(unscoped_variables)
|
||||||
|
@ -26,15 +26,15 @@ blipper = {}
|
||||||
--- Build an object that simply "blips" between the given images at the given interval.
|
--- Build an object that simply "blips" between the given images at the given interval.
|
||||||
--- Expects `playdate.graphics.animation.blinker.updateAll()` to be called on every update.
|
--- Expects `playdate.graphics.animation.blinker.updateAll()` to be called on every update.
|
||||||
function blipper.new(msInterval, imagePath1, imagePath2)
|
function blipper.new(msInterval, imagePath1, imagePath2)
|
||||||
local blinker = playdate.graphics.animation.blinker.new(msInterval, msInterval, true)
|
local blinker = playdate.graphics.animation.blinker.new(msInterval, msInterval, true)
|
||||||
blinker:start()
|
blinker:start()
|
||||||
return {
|
return {
|
||||||
blinker = blinker,
|
blinker = blinker,
|
||||||
image1 = playdate.graphics.image.new(imagePath1),
|
image1 = playdate.graphics.image.new(imagePath1),
|
||||||
image2 = playdate.graphics.image.new(imagePath2),
|
image2 = playdate.graphics.image.new(imagePath2),
|
||||||
draw = function(self, disableBlipping, x, y)
|
draw = function(self, disableBlipping, x, y)
|
||||||
local currentImage = (disableBlipping or self.blinker.on) and self.image2 or self.image1
|
local currentImage = (disableBlipping or self.blinker.on) and self.image2 or self.image1
|
||||||
currentImage:draw(x, y)
|
currentImage:draw(x, y)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
908
src/main.lua
908
src/main.lua
File diff suppressed because it is too large
Load Diff
|
@ -10,53 +10,53 @@ local IndicatorWidth <const> = ScoreFont:getTextWidth(Indicator)
|
||||||
---@param battingTeam any
|
---@param battingTeam any
|
||||||
---@return string, number, string, number
|
---@return string, number, string, number
|
||||||
function getIndicators(teams, battingTeam)
|
function getIndicators(teams, battingTeam)
|
||||||
if teams.home == battingTeam then
|
if teams.home == battingTeam then
|
||||||
return Indicator, 0, "", IndicatorWidth
|
return Indicator, 0, "", IndicatorWidth
|
||||||
end
|
end
|
||||||
return "", IndicatorWidth, Indicator, 0
|
return "", IndicatorWidth, Indicator, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawScoreboard(x, y, teams, outs, battingTeam, inning)
|
function drawScoreboard(x, y, teams, outs, battingTeam, inning)
|
||||||
local gfx = playdate.graphics
|
local gfx = playdate.graphics
|
||||||
|
|
||||||
local homeScore = teams.home.score
|
local homeScore = teams.home.score
|
||||||
local awayScore = teams.away.score
|
local awayScore = teams.away.score
|
||||||
|
|
||||||
local homeIndicator, homeOffset, awayIndicator, awayOffset = getIndicators(teams, battingTeam)
|
local homeIndicator, homeOffset, awayIndicator, awayOffset = getIndicators(teams, battingTeam)
|
||||||
|
|
||||||
local homeScoreText = homeIndicator .. "HOME " .. (homeScore > 9 and homeScore or " " .. homeScore)
|
local homeScoreText = homeIndicator .. "HOME " .. (homeScore > 9 and homeScore or " " .. homeScore)
|
||||||
local awayScoreText = awayIndicator .. "AWAY " .. (awayScore > 9 and awayScore or " " .. awayScore)
|
local awayScoreText = awayIndicator .. "AWAY " .. (awayScore > 9 and awayScore or " " .. awayScore)
|
||||||
|
|
||||||
local rectWidth = (ScoreboardMarginX * 2)
|
local rectWidth = (ScoreboardMarginX * 2)
|
||||||
+ ScoreboardMarginRight
|
+ ScoreboardMarginRight
|
||||||
+ ScoreFont:getTextWidth(homeScoreText)
|
+ ScoreFont:getTextWidth(homeScoreText)
|
||||||
+ homeOffset
|
+ homeOffset
|
||||||
|
|
||||||
gfx.setLineWidth(1)
|
gfx.setLineWidth(1)
|
||||||
gfx.setColor(gfx.kColorBlack)
|
gfx.setColor(gfx.kColorBlack)
|
||||||
gfx.fillRect(x, y, rectWidth, ScoreboardHeight)
|
gfx.fillRect(x, y, rectWidth, ScoreboardHeight)
|
||||||
|
|
||||||
local originalDrawMode = gfx.getImageDrawMode()
|
local originalDrawMode = gfx.getImageDrawMode()
|
||||||
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
gfx.setImageDrawMode(gfx.kDrawModeInverted)
|
||||||
|
|
||||||
ScoreFont:drawText(homeScoreText, x + ScoreboardMarginX + homeOffset, y + 6)
|
ScoreFont:drawText(homeScoreText, x + ScoreboardMarginX + homeOffset, y + 6)
|
||||||
ScoreFont:drawText(awayScoreText, x + ScoreboardMarginX + awayOffset, y + 22)
|
ScoreFont:drawText(awayScoreText, x + ScoreboardMarginX + awayOffset, y + 22)
|
||||||
local inningOffsetX = (x + ScoreboardMarginX + IndicatorWidth) + (4 * 2.5 * OutBubbleRadius)
|
local inningOffsetX = (x + ScoreboardMarginX + IndicatorWidth) + (4 * 2.5 * OutBubbleRadius)
|
||||||
ScoreFont:drawText(inning, inningOffsetX, y + 39)
|
ScoreFont:drawText(inning, inningOffsetX, y + 39)
|
||||||
|
|
||||||
gfx.setImageDrawMode(originalDrawMode)
|
gfx.setImageDrawMode(originalDrawMode)
|
||||||
|
|
||||||
gfx.setColor(gfx.kColorWhite)
|
gfx.setColor(gfx.kColorWhite)
|
||||||
|
|
||||||
function circleParams(i)
|
function circleParams(i)
|
||||||
local circleOffset = i * 2.5 * OutBubbleRadius
|
local circleOffset = i * 2.5 * OutBubbleRadius
|
||||||
return (x + ScoreboardMarginX + OutBubbleRadius + IndicatorWidth) + circleOffset, y + 46, OutBubbleRadius
|
return (x + ScoreboardMarginX + OutBubbleRadius + IndicatorWidth) + circleOffset, y + 46, OutBubbleRadius
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = outs, 2 do
|
for i = outs, 2 do
|
||||||
gfx.drawCircleAtPoint(circleParams(i))
|
gfx.drawCircleAtPoint(circleParams(i))
|
||||||
end
|
end
|
||||||
for i = 0, (outs - 1) do
|
for i = 0, (outs - 1) do
|
||||||
gfx.fillCircleAtPoint(circleParams(i))
|
gfx.fillCircleAtPoint(circleParams(i))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
142
src/utils.lua
142
src/utils.lua
|
@ -4,40 +4,40 @@ import 'CoreLibs/graphics.lua'
|
||||||
-- stylua: ignore end
|
-- stylua: ignore end
|
||||||
|
|
||||||
function easingHill(t, b, c, d)
|
function easingHill(t, b, c, d)
|
||||||
c = c + 0.0 -- convert to float to prevent integer overflow
|
c = c + 0.0 -- convert to float to prevent integer overflow
|
||||||
t = t / d
|
t = t / d
|
||||||
t = ((t * 2) - 1)
|
t = ((t * 2) - 1)
|
||||||
t = t * t
|
t = t * t
|
||||||
return (c * t) + b
|
return (c * t) + b
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Useful for quick print-the-value-in-place debugging.
|
-- Useful for quick print-the-value-in-place debugging.
|
||||||
-- selene: allow(unused_variable)
|
-- selene: allow(unused_variable)
|
||||||
function label(value, name)
|
function label(value, name)
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
print(name .. ":")
|
print(name .. ":")
|
||||||
printTable(value)
|
printTable(value)
|
||||||
else
|
else
|
||||||
print(name .. ": " .. value)
|
print(name .. ": " .. value)
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param x number
|
---@param x number
|
||||||
---@param y number
|
---@param y number
|
||||||
---@return XYPair
|
---@return XYPair
|
||||||
function xy(x, y)
|
function xy(x, y)
|
||||||
return {
|
return {
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the normalized vector as two values, plus the distance between the given points.
|
--- Returns the normalized vector as two values, plus the distance between the given points.
|
||||||
---@return number, number, number
|
---@return number, number, number
|
||||||
function normalizeVector(x1, y1, x2, y2)
|
function normalizeVector(x1, y1, x2, y2)
|
||||||
local distance, a, b = distanceBetween(x1, y1, x2, y2)
|
local distance, a, b = distanceBetween(x1, y1, x2, y2)
|
||||||
return a / distance, b / distance, distance
|
return a / distance, b / distance, distance
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
|
@ -45,41 +45,41 @@ end
|
||||||
---@param condition fun(T): boolean
|
---@param condition fun(T): boolean
|
||||||
---@return T[]
|
---@return T[]
|
||||||
function filter(array, condition)
|
function filter(array, condition)
|
||||||
local newArray = {}
|
local newArray = {}
|
||||||
for _, element in pairs(array) do
|
for _, element in pairs(array) do
|
||||||
if condition(element) then
|
if condition(element) then
|
||||||
newArray[#newArray + 1] = element
|
newArray[#newArray + 1] = element
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return newArray
|
return newArray
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return number, number, number
|
---@return number, number, number
|
||||||
function distanceBetween(x1, y1, x2, y2)
|
function distanceBetween(x1, y1, x2, y2)
|
||||||
local a = x1 - x2
|
local a = x1 - x2
|
||||||
local b = y1 - y2
|
local b = y1 - y2
|
||||||
return math.sqrt((a * a) + (b * b)), a, b
|
return math.sqrt((a * a) + (b * b)), a, b
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound
|
--- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound
|
||||||
--- @return boolean
|
--- @return boolean
|
||||||
function pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)
|
function pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)
|
||||||
-- This check currently assumes right-handedness.
|
-- This check currently assumes right-handedness.
|
||||||
-- I.e. it assumes the ball is to the right of batBaseX
|
-- I.e. it assumes the ball is to the right of batBaseX
|
||||||
if pointX < lineX1 or pointX > lineX2 or pointY > bottomBound then
|
if pointX < lineX1 or pointX > lineX2 or pointY > bottomBound then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local m = (lineY2 - lineY1) / (lineX2 - lineX1)
|
local m = (lineY2 - lineY1) / (lineX2 - lineX1)
|
||||||
|
|
||||||
-- y = mx + b
|
-- y = mx + b
|
||||||
-- b = y1 - (m * x1)
|
-- b = y1 - (m * x1)
|
||||||
local b = lineY1 - (m * lineX1)
|
local b = lineY1 - (m * lineX1)
|
||||||
local yOnLine = (m * pointX) + b
|
local yOnLine = (m * pointX) + b
|
||||||
local yP = pointY
|
local yP = pointY
|
||||||
local yDelta = yOnLine - yP
|
local yDelta = yOnLine - yP
|
||||||
|
|
||||||
return yDelta <= 0
|
return yDelta <= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the nearest position object from the given point, as well as its distance from that point
|
--- Returns the nearest position object from the given point, as well as its distance from that point
|
||||||
|
@ -89,23 +89,23 @@ end
|
||||||
---@param y number
|
---@param y number
|
||||||
---@return T,number|nil
|
---@return T,number|nil
|
||||||
function getNearestOf(array, x, y, extraCondition)
|
function getNearestOf(array, x, y, extraCondition)
|
||||||
local nearest, nearestDistance = nil, nil
|
local nearest, nearestDistance = nil, nil
|
||||||
for _, element in pairs(array) do
|
for _, element in pairs(array) do
|
||||||
if not extraCondition or extraCondition(element) then
|
if not extraCondition or extraCondition(element) then
|
||||||
if nearest == nil then
|
if nearest == nil then
|
||||||
nearest = element
|
nearest = element
|
||||||
nearestDistance = distanceBetween(element.x, element.y, x, y)
|
nearestDistance = distanceBetween(element.x, element.y, x, y)
|
||||||
else
|
else
|
||||||
local distance = distanceBetween(element.x, element.y, x, y)
|
local distance = distanceBetween(element.x, element.y, x, y)
|
||||||
if distance < nearestDistance then
|
if distance < nearestDistance then
|
||||||
nearest = element
|
nearest = element
|
||||||
nearestDistance = distance
|
nearestDistance = distance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nearest, nearestDistance
|
return nearest, nearestDistance
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Marker used by buildCache to indicate a cached `nil` value.
|
--- Marker used by buildCache to indicate a cached `nil` value.
|
||||||
|
@ -122,18 +122,18 @@ local NoValue <const> = {}
|
||||||
---@generic Value
|
---@generic Value
|
||||||
---@return { get: fun(key: Key): Value }
|
---@return { get: fun(key: Key): Value }
|
||||||
function buildCache(fetcher)
|
function buildCache(fetcher)
|
||||||
local cacheData = {}
|
local cacheData = {}
|
||||||
return {
|
return {
|
||||||
get = function(key)
|
get = function(key)
|
||||||
if cacheData[key] == NoValue then
|
if cacheData[key] == NoValue then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
if cacheData[key] ~= nil then
|
if cacheData[key] ~= nil then
|
||||||
return cacheData[key]
|
return cacheData[key]
|
||||||
end
|
end
|
||||||
local fetched = fetcher(key)
|
local fetched = fetcher(key)
|
||||||
cacheData[key] = fetched ~= nil and fetched or NoValue
|
cacheData[key] = fetched ~= nil and fetched or NoValue
|
||||||
return cacheData[key]
|
return cacheData[key]
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue