parent
0b126919ac
commit
4fc37b133e
3
Makefile
3
Makefile
|
@ -1,3 +1,6 @@
|
||||||
|
lint:
|
||||||
|
stylua src/
|
||||||
|
|
||||||
all:
|
all:
|
||||||
pdc src BatterUp.pdx
|
pdc src BatterUp.pdx
|
||||||
|
|
||||||
|
|
55
src/ecs.lua
55
src/ecs.lua
|
@ -1,4 +1,4 @@
|
||||||
ecs = { }
|
ecs = {}
|
||||||
|
|
||||||
local ALL_ENTITIES = {}
|
local ALL_ENTITIES = {}
|
||||||
|
|
||||||
|
@ -61,20 +61,21 @@ 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()
|
return function() end
|
||||||
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 indent = 0 end
|
if not indent then
|
||||||
|
indent = 0
|
||||||
|
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)
|
||||||
|
@ -87,7 +88,7 @@ function addSystem(callback, keys, shapes)
|
||||||
callback = callback,
|
callback = callback,
|
||||||
keys = keys,
|
keys = keys,
|
||||||
shapes = shapes,
|
shapes = shapes,
|
||||||
entityCache = nil
|
entityCache = nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -98,18 +99,26 @@ 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(ALL_ENTITIES) do
|
for entity, _ in pairs(ALL_ENTITIES) 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(deltaSeconds, entity, entity[keys[1]], entity[keys[2]], entity[keys[3]], entity[keys[4]], entity)
|
system.callback(
|
||||||
|
deltaSeconds,
|
||||||
|
entity,
|
||||||
|
entity[keys[1]],
|
||||||
|
entity[keys[2]],
|
||||||
|
entity[keys[3]],
|
||||||
|
entity[keys[4]],
|
||||||
|
entity
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -130,11 +139,11 @@ 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
|
||||||
|
@ -143,8 +152,8 @@ function ecs.forEntitiesWith(tShape, uShape, vShape, wShape, finalFunc)
|
||||||
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
|
||||||
|
@ -159,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
|
||||||
|
@ -183,14 +192,14 @@ 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")
|
||||||
|
@ -200,12 +209,12 @@ ecs.forEntitiesWith(Position, Velocity, function (delta, e, pos, vel)
|
||||||
})
|
})
|
||||||
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)
|
86
src/main.lua
86
src/main.lua
|
@ -1,3 +1,4 @@
|
||||||
|
-- stylua: ignore start
|
||||||
import 'CoreLibs/animation.lua'
|
import 'CoreLibs/animation.lua'
|
||||||
import 'CoreLibs/animator.lua'
|
import 'CoreLibs/animator.lua'
|
||||||
import 'CoreLibs/easing.lua'
|
import 'CoreLibs/easing.lua'
|
||||||
|
@ -7,6 +8,7 @@ import 'CoreLibs/ui.lua'
|
||||||
|
|
||||||
import 'graphics.lua'
|
import 'graphics.lua'
|
||||||
import 'utils.lua'
|
import 'utils.lua'
|
||||||
|
-- stylua: ignore end
|
||||||
|
|
||||||
--- @alias XYPair { x: number, y: number }
|
--- @alias XYPair { x: number, y: number }
|
||||||
|
|
||||||
|
@ -20,7 +22,7 @@ local gfx = playdate.graphics
|
||||||
|
|
||||||
local SCREEN = {
|
local SCREEN = {
|
||||||
W = playdate.display.getWidth(),
|
W = playdate.display.getWidth(),
|
||||||
H = playdate.display.getHeight()
|
H = playdate.display.getHeight(),
|
||||||
}
|
}
|
||||||
|
|
||||||
local CENTER = xy(SCREEN.W / 2, SCREEN.H / 2)
|
local CENTER = xy(SCREEN.W / 2, SCREEN.H / 2)
|
||||||
|
@ -29,17 +31,13 @@ local batCrackSound = playdate.sound.sampleplayer.new("sounds/bat-crack-reverb.w
|
||||||
local grassBackground = gfx.image.new("images/game/grass.png") --[[@as PlaydateGraphicsImage]]
|
local grassBackground = gfx.image.new("images/game/grass.png") --[[@as PlaydateGraphicsImage]]
|
||||||
local playerFrown = gfx.image.new("images/game/player-frown.png") --[[@as PlaydateGraphicsImage]]
|
local playerFrown = gfx.image.new("images/game/player-frown.png") --[[@as PlaydateGraphicsImage]]
|
||||||
|
|
||||||
local playerImageBlipper = blipper.new(
|
local playerImageBlipper = blipper.new(100, "images/game/player.png", "images/game/player-lowhat.png")
|
||||||
100,
|
|
||||||
"images/game/player.png",
|
|
||||||
"images/game/player-lowhat.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
local BALL_OFFSCREEN = 999
|
local BALL_OFFSCREEN = 999
|
||||||
|
|
||||||
local danceBounceMs = 500
|
local danceBounceMs = 500
|
||||||
local danceBounceCount = 4
|
local danceBounceCount = 4
|
||||||
local fielderDanceAnimator = gfx.animator.new(danceBounceMs, 10, 0, easingHill)--, -1 * danceBounceMs * danceBounceCount)
|
local fielderDanceAnimator = gfx.animator.new(danceBounceMs, 10, 0, easingHill) --, -1 * danceBounceMs * danceBounceCount)
|
||||||
fielderDanceAnimator.repeatCount = danceBounceCount - 1
|
fielderDanceAnimator.repeatCount = danceBounceCount - 1
|
||||||
|
|
||||||
local pitchFlyTimeMs = 2500
|
local pitchFlyTimeMs = 2500
|
||||||
|
@ -56,14 +54,14 @@ local TAG_DISTANCE = 20
|
||||||
local ball = {
|
local ball = {
|
||||||
x = CENTER.x,
|
x = CENTER.x,
|
||||||
y = BALL_OFFSCREEN,
|
y = BALL_OFFSCREEN,
|
||||||
size = 6
|
size = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
local BAT_LENGTH = 45
|
local BAT_LENGTH = 45
|
||||||
|
|
||||||
local MODES = {
|
local MODES = {
|
||||||
batting = {},
|
batting = {},
|
||||||
running = {}
|
running = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local currentMode = MODES.batting
|
local currentMode = MODES.batting
|
||||||
|
@ -87,19 +85,19 @@ local bases = {
|
||||||
xy(SCREEN.W * 0.93, SCREEN.H * 0.52),
|
xy(SCREEN.W * 0.93, SCREEN.H * 0.52),
|
||||||
xy(SCREEN.W * 0.47, SCREEN.H * 0.19),
|
xy(SCREEN.W * 0.47, SCREEN.H * 0.19),
|
||||||
xy(SCREEN.W * 0.03, SCREEN.H * 0.52),
|
xy(SCREEN.W * 0.03, SCREEN.H * 0.52),
|
||||||
xy(SCREEN.W * 0.474, SCREEN.H * 0.79)
|
xy(SCREEN.W * 0.474, SCREEN.H * 0.79),
|
||||||
}
|
}
|
||||||
|
|
||||||
---@type table<Base, Base>
|
---@type table<Base, Base>
|
||||||
local nextBaseMap = {
|
local nextBaseMap = {
|
||||||
[bases[FIRST]] = bases[SECOND],
|
[bases[FIRST]] = bases[SECOND],
|
||||||
[bases[SECOND]] = bases[THIRD],
|
[bases[SECOND]] = bases[THIRD],
|
||||||
[bases[THIRD]] = bases[HOME]
|
[bases[THIRD]] = bases[HOME],
|
||||||
}
|
}
|
||||||
|
|
||||||
function newFielder(speed)
|
function newFielder(speed)
|
||||||
return {
|
return {
|
||||||
speed = speed
|
speed = speed,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,19 +111,19 @@ local fielders = {
|
||||||
catcher = newFielder(20),
|
catcher = newFielder(20),
|
||||||
left = newFielder(40),
|
left = newFielder(40),
|
||||||
center = newFielder(40),
|
center = newFielder(40),
|
||||||
right = newFielder(40)
|
right = newFielder(40),
|
||||||
}
|
}
|
||||||
|
|
||||||
local PITCHER_POS = {
|
local PITCHER_POS = {
|
||||||
x = SCREEN.W * 0.48,
|
x = SCREEN.W * 0.48,
|
||||||
y = SCREEN.H * 0.40
|
y = SCREEN.H * 0.40,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Resets the target positions of all fielders to their defaults (at their field positions).
|
--- Resets the target positions of all fielders to their defaults (at their field positions).
|
||||||
---@param fromOffTheField boolean If provided, also sets all runners' current position to one centralized location.
|
---@param fromOffTheField boolean If provided, also sets all runners' current position to one centralized location.
|
||||||
function resetFielderPositions(fromOffTheField)
|
function resetFielderPositions(fromOffTheField)
|
||||||
if fromOffTheField then
|
if fromOffTheField then
|
||||||
for _,fielder in pairs(fielders) do
|
for _, fielder in pairs(fielders) do
|
||||||
fielder.x = CENTER.x
|
fielder.x = CENTER.x
|
||||||
fielder.y = SCREEN.H
|
fielder.y = SCREEN.H
|
||||||
end
|
end
|
||||||
|
@ -146,13 +144,13 @@ local PLAYER_STARTING_X = bases[HOME].x - 40
|
||||||
local PLAYER_STARTING_Y = bases[HOME].y - 3
|
local PLAYER_STARTING_Y = bases[HOME].y - 3
|
||||||
|
|
||||||
--- @type Runner[]
|
--- @type Runner[]
|
||||||
local runners = { }
|
local runners = {}
|
||||||
|
|
||||||
--- @type Runner[]
|
--- @type Runner[]
|
||||||
local outRunners = { }
|
local outRunners = {}
|
||||||
|
|
||||||
local nameI = 1
|
local nameI = 1
|
||||||
local runnerNames = {"Barbara", "Steve", "Jerry", "Beatrice"}
|
local runnerNames = { "Barbara", "Steve", "Jerry", "Beatrice" }
|
||||||
|
|
||||||
---@return Runner
|
---@return Runner
|
||||||
function newRunner()
|
function newRunner()
|
||||||
|
@ -161,7 +159,7 @@ function newRunner()
|
||||||
y = PLAYER_STARTING_Y,
|
y = PLAYER_STARTING_Y,
|
||||||
nextBase = nil,
|
nextBase = nil,
|
||||||
prevBase = nil,
|
prevBase = nil,
|
||||||
name = runnerNames[nameI]
|
name = runnerNames[nameI],
|
||||||
}
|
}
|
||||||
nameI = nameI + 1
|
nameI = nameI + 1
|
||||||
runners[#runners + 1] = new
|
runners[#runners + 1] = new
|
||||||
|
@ -221,7 +219,7 @@ local crankChange = 0
|
||||||
local BASE_HITBOX = 13
|
local BASE_HITBOX = 13
|
||||||
--- Returns the base being touched by the runner at (x,y), or nil, if no base is being touched
|
--- Returns the base being touched by the runner at (x,y), or nil, if no base is being touched
|
||||||
function isTouchingBase(x, y)
|
function isTouchingBase(x, y)
|
||||||
for _,base in ipairs(bases) do
|
for _, base in ipairs(bases) do
|
||||||
if distanceBetween(x, y, base.x, base.y) < BASE_HITBOX then
|
if distanceBetween(x, y, base.x, base.y) < BASE_HITBOX then
|
||||||
return base
|
return base
|
||||||
end
|
end
|
||||||
|
@ -236,8 +234,7 @@ function isTouchingBall(x, y)
|
||||||
return ballDistance < BALL_CATCH_HITBOX
|
return ballDistance < BALL_CATCH_HITBOX
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateForcedTos()
|
function updateForcedTos() end
|
||||||
end
|
|
||||||
|
|
||||||
local outs = 0
|
local outs = 0
|
||||||
local homeScore = 0
|
local homeScore = 0
|
||||||
|
@ -246,20 +243,18 @@ local awayScore = 0
|
||||||
function outRunner(runnerIndex)
|
function outRunner(runnerIndex)
|
||||||
print("You're out, runner" .. runnerIndex .. "!")
|
print("You're out, runner" .. runnerIndex .. "!")
|
||||||
outs = math.min(3, outs + 1)
|
outs = math.min(3, outs + 1)
|
||||||
outRunners[#outRunners+1] = runners[runnerIndex]
|
outRunners[#outRunners + 1] = runners[runnerIndex]
|
||||||
table.remove(runners, runnerIndex)
|
table.remove(runners, runnerIndex)
|
||||||
updateForcedTos()
|
updateForcedTos()
|
||||||
fielderDanceAnimator:reset()
|
fielderDanceAnimator:reset()
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateFielders()
|
function updateFielders()
|
||||||
local touchingBaseCache = buildCache(
|
local touchingBaseCache = buildCache(function(runner)
|
||||||
function(runner)
|
|
||||||
return isTouchingBase(runner.x, runner.y)
|
return isTouchingBase(runner.x, runner.y)
|
||||||
end
|
end)
|
||||||
)
|
|
||||||
|
|
||||||
for _,fielder in pairs(fielders) do
|
for _, fielder in pairs(fielders) do
|
||||||
-- TODO: Target unforced runners (or their target bases) for tagging
|
-- TODO: Target unforced runners (or their target bases) for tagging
|
||||||
-- With new Position-based scheme, fielders are now able to set `fielder.target = runner` to track directly
|
-- With new Position-based scheme, fielders are now able to set `fielder.target = runner` to track directly
|
||||||
if fielder.target ~= nil then
|
if fielder.target ~= nil then
|
||||||
|
@ -278,7 +273,7 @@ function updateFielders()
|
||||||
|
|
||||||
if currentMode == MODES.running and isTouchingBall(fielder.x, fielder.y) then
|
if currentMode == MODES.running and isTouchingBall(fielder.x, fielder.y) then
|
||||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||||
for i,runner in pairs(runners) do
|
for i, runner in pairs(runners) do
|
||||||
local runnerOnBase = touchingBaseCache.get(runner)
|
local runnerOnBase = touchingBaseCache.get(runner)
|
||||||
if touchedBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then
|
if touchedBase and runner.forcedTo == touchedBase and touchedBase ~= runnerOnBase then
|
||||||
print("Force out of runner:")
|
print("Force out of runner:")
|
||||||
|
@ -301,12 +296,12 @@ end
|
||||||
function updateRunners()
|
function updateRunners()
|
||||||
local autoRunSpeed = 20
|
local autoRunSpeed = 20
|
||||||
--autoRunSpeed = 140
|
--autoRunSpeed = 140
|
||||||
local nonPlayerRunners = filter(runners, function (runner)
|
local nonPlayerRunners = filter(runners, function(runner)
|
||||||
return runner ~= batter
|
return runner ~= batter
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local runnerMoved = false
|
local runnerMoved = false
|
||||||
for _,runner in pairs(nonPlayerRunners) do
|
for _, runner in pairs(nonPlayerRunners) do
|
||||||
local _, nearestBaseDistance = getNearestOf(bases, runner.x, runner.y)
|
local _, nearestBaseDistance = getNearestOf(bases, runner.x, runner.y)
|
||||||
if runner.nextBase then
|
if runner.nextBase then
|
||||||
local nb = runner.nextBase
|
local nb = runner.nextBase
|
||||||
|
@ -345,7 +340,7 @@ function throwArrivedBeforeRunner()
|
||||||
end
|
end
|
||||||
|
|
||||||
function getRunnerTargeting(base)
|
function getRunnerTargeting(base)
|
||||||
for _,runner in pairs(runners) do
|
for _, runner in pairs(runners) do
|
||||||
if runner.nextBase == base then
|
if runner.nextBase == base then
|
||||||
return runner
|
return runner
|
||||||
end
|
end
|
||||||
|
@ -356,10 +351,10 @@ end
|
||||||
---@return Base[]
|
---@return Base[]
|
||||||
function getForcedOutTargets()
|
function getForcedOutTargets()
|
||||||
local targets = {}
|
local targets = {}
|
||||||
for _,base in ipairs(bases) do
|
for _, base in ipairs(bases) do
|
||||||
local runnerTargetingBase = getRunnerTargeting(base)
|
local runnerTargetingBase = getRunnerTargeting(base)
|
||||||
if runnerTargetingBase then
|
if runnerTargetingBase then
|
||||||
targets[#targets+1] = base
|
targets[#targets + 1] = base
|
||||||
else
|
else
|
||||||
return targets
|
return targets
|
||||||
end
|
end
|
||||||
|
@ -372,7 +367,7 @@ end
|
||||||
---@return { x: number, y: number } | nil, number | nil
|
---@return { x: number, y: number } | nil, number | nil
|
||||||
function getBaseOfStrandedRunner()
|
function getBaseOfStrandedRunner()
|
||||||
local farRunnersBase, farDistance
|
local farRunnersBase, farDistance
|
||||||
for _,runner in pairs(runners) do
|
for _, runner in pairs(runners) do
|
||||||
local base, distance = getNearestOf(bases, runner.x, runner.y, function(base)
|
local base, distance = getNearestOf(bases, runner.x, runner.y, function(base)
|
||||||
return runner.nextBase == base
|
return runner.nextBase == base
|
||||||
end)
|
end)
|
||||||
|
@ -431,8 +426,10 @@ function updateBatting()
|
||||||
batTip.x = batBase.x + (BAT_LENGTH * math.sin(batAngle))
|
batTip.x = batBase.x + (BAT_LENGTH * math.sin(batAngle))
|
||||||
batTip.y = batBase.y + (BAT_LENGTH * math.cos(batAngle))
|
batTip.y = batBase.y + (BAT_LENGTH * math.cos(batAngle))
|
||||||
|
|
||||||
if acceleratedChange >= 0 and
|
if
|
||||||
pointDirectlyUnderLine(ball.x, ball.y, batBase.x, batBase.y, batTip.x, batTip.y, SCREEN.H) then
|
acceleratedChange >= 0
|
||||||
|
and pointDirectlyUnderLine(ball.x, ball.y, batBase.x, batBase.y, batTip.x, batTip.y, SCREEN.H)
|
||||||
|
then
|
||||||
batCrackSound:play()
|
batCrackSound:play()
|
||||||
currentMode = MODES.running
|
currentMode = MODES.running
|
||||||
ballAngle = batAngle + math.rad(90)
|
ballAngle = batAngle + math.rad(90)
|
||||||
|
@ -525,10 +522,10 @@ function drawScoreboard()
|
||||||
gfx.fillRect(x - 15, y - 44, 73, 55)
|
gfx.fillRect(x - 15, y - 44, 73, 55)
|
||||||
|
|
||||||
gfx.setColor(gfx.kColorWhite)
|
gfx.setColor(gfx.kColorWhite)
|
||||||
for i=outs,2 do
|
for i = outs, 2 do
|
||||||
gfx.drawCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
|
gfx.drawCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
|
||||||
end
|
end
|
||||||
for i=0,(outs - 1) do
|
for i = 0, (outs - 1) do
|
||||||
gfx.fillCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
|
gfx.fillCircleAtPoint(x + (i * 2.5 * OUT_BUBBLE_SIZE), y, OUT_BUBBLE_SIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -559,16 +556,13 @@ function playdate.update()
|
||||||
gfx.drawCircleAtPoint(ball.x, ball.y, ball.size)
|
gfx.drawCircleAtPoint(ball.x, ball.y, ball.size)
|
||||||
|
|
||||||
local fielderDanceHeight = fielderDanceAnimator:currentValue()
|
local fielderDanceHeight = fielderDanceAnimator:currentValue()
|
||||||
for _,fielder in pairs(fielders) do
|
for _, fielder in pairs(fielders) do
|
||||||
gfx.fillRect(fielder.x, fielder.y - fielderDanceHeight, 14, 25)
|
gfx.fillRect(fielder.x, fielder.y - fielderDanceHeight, 14, 25)
|
||||||
end
|
end
|
||||||
|
|
||||||
if currentMode == MODES.batting then
|
if currentMode == MODES.batting then
|
||||||
gfx.setLineWidth(5)
|
gfx.setLineWidth(5)
|
||||||
gfx.drawLine(
|
gfx.drawLine(batBase.x, batBase.y, batTip.x, batTip.y)
|
||||||
batBase.x, batBase.y,
|
|
||||||
batTip.x, batTip.y
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if playdate.isCrankDocked() then -- or (crankChange < 2 and currentMode == MODES.running) then
|
if playdate.isCrankDocked() then -- or (crankChange < 2 and currentMode == MODES.running) then
|
||||||
|
@ -576,11 +570,11 @@ function playdate.update()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO? Change blip speed depending on runner speed?
|
-- TODO? Change blip speed depending on runner speed?
|
||||||
for _,runner in pairs(runners) do
|
for _, runner in pairs(runners) do
|
||||||
-- TODO? Scale sprites down as y increases
|
-- TODO? Scale sprites down as y increases
|
||||||
playerImageBlipper:draw(false, runner.x, runner.y)
|
playerImageBlipper:draw(false, runner.x, runner.y)
|
||||||
end
|
end
|
||||||
for _,runner in pairs(outRunners) do
|
for _, runner in pairs(outRunners) do
|
||||||
playerFrown:draw(runner.x, runner.y)
|
playerFrown:draw(runner.x, runner.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
-- stylua: ignore start
|
||||||
import 'CoreLibs/animation.lua'
|
import 'CoreLibs/animation.lua'
|
||||||
import 'CoreLibs/graphics.lua'
|
import 'CoreLibs/graphics.lua'
|
||||||
|
-- stylua: ignore end
|
||||||
|
|
||||||
-- number = ((number * 2) - 1)
|
-- number = ((number * 2) - 1)
|
||||||
-- return number * number
|
-- return number * number
|
||||||
|
@ -21,7 +23,7 @@ end
|
||||||
function xy(x, y)
|
function xy(x, y)
|
||||||
return {
|
return {
|
||||||
x = x,
|
x = x,
|
||||||
y = y
|
y = y,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ end
|
||||||
---@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
|
||||||
|
@ -53,7 +55,7 @@ end
|
||||||
---@return TOut[]
|
---@return TOut[]
|
||||||
function map(array, mapper)
|
function map(array, mapper)
|
||||||
local newArray = {}
|
local newArray = {}
|
||||||
for _,element in pairs(array) do
|
for _, element in pairs(array) do
|
||||||
newArray[#newArray + 1] = mapper(element)
|
newArray[#newArray + 1] = mapper(element)
|
||||||
end
|
end
|
||||||
return newArray
|
return newArray
|
||||||
|
@ -63,7 +65,7 @@ end
|
||||||
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
|
||||||
|
@ -128,7 +130,7 @@ function buildCache(fetcher)
|
||||||
end
|
end
|
||||||
cacheData[key] = fetcher(key) or NO_VALUE
|
cacheData[key] = fetcher(key) or NO_VALUE
|
||||||
return cacheData[key]
|
return cacheData[key]
|
||||||
end
|
end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,6 +148,6 @@ function blipper.new(msInterval, imagePath1, 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
|
Loading…
Reference in New Issue