diff --git a/src/assets.lua b/src/assets.lua index 5789cd2..b921f7e 100644 --- a/src/assets.lua +++ b/src/assets.lua @@ -1,6 +1,9 @@ -- GENERATED FILE - DO NOT EDIT -- Instead, edit the source file directly: assets.lua2p. +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) +DarkPlayerBack = playdate.graphics.image.new("images/game/DarkPlayerBack.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) Glove = playdate.graphics.image.new("images/game/Glove.png") @@ -9,25 +12,37 @@ Glove = playdate.graphics.image.new("images/game/Glove.png") PlayerFrown = playdate.graphics.image.new("images/game/PlayerFrown.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) -PlayerBack = playdate.graphics.image.new("images/game/PlayerBack.png") ---selene: allow(unused_variable) ---selene: allow(unscoped_variables) -PlayerLowHat = playdate.graphics.image.new("images/game/PlayerLowHat.png") +BaseLogo = playdate.graphics.image.new("images/game/BaseLogo.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) GloveHoldingBall = playdate.graphics.image.new("images/game/GloveHoldingBall.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) +Hat = playdate.graphics.image.new("images/game/Hat.png") +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) +DarkPlayerBase = playdate.graphics.image.new("images/game/DarkPlayerBase.png") +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) MenuImage = playdate.graphics.image.new("images/game/MenuImage.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) -Player = playdate.graphics.image.new("images/game/Player.png") +PlayerSmile = playdate.graphics.image.new("images/game/PlayerSmile.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) Minimap = playdate.graphics.image.new("images/game/Minimap.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) +FrownLogo = playdate.graphics.image.new("images/game/FrownLogo.png") +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) GrassBackground = playdate.graphics.image.new("images/game/GrassBackground.png") +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) +LightPlayerBase = playdate.graphics.image.new("images/game/LightPlayerBase.png") +--selene: allow(unused_variable) +--selene: allow(unscoped_variables) +LightPlayerBack = playdate.graphics.image.new("images/game/LightPlayerBack.png") --selene: allow(unused_variable) --selene: allow(unscoped_variables) diff --git a/src/baserunning.lua b/src/baserunning.lua index 1626207..0897c73 100644 --- a/src/baserunning.lua +++ b/src/baserunning.lua @@ -129,6 +129,7 @@ end ---@return Runner function Baserunning:newRunner() local new = { + -- imageSet = math.random() < C.WokeMeter and FemmeSet or MascSet, -- TODO? lol. x = C.RightHandedBattersBox.x - 60, y = C.RightHandedBattersBox.y + 60, nextBase = C.RightHandedBattersBox, diff --git a/src/draw/fielder.lua b/src/draw/fielder.lua index e908d9f..39ff001 100644 --- a/src/draw/fielder.lua +++ b/src/draw/fielder.lua @@ -1,6 +1,3 @@ --- selene: allow(shadowing) -local gfx = playdate.graphics - local GloveSizeX, GloveSizeY = Glove:getSize() local GloveOffX, GloveOffY = GloveSizeX / 2, GloveSizeY / 2 @@ -10,7 +7,7 @@ local GloveOffX, GloveOffY = GloveSizeX / 2, GloveSizeY / 2 ---@return boolean isHoldingBall local function drawFielderGlove(ball, fielderX, fielderY) local distanceFromBall = utils.distanceBetweenZ(fielderX, fielderY, 0, ball.x, ball.y, ball.z) - local shoulderX, shoulderY = fielderX + 10, fielderY + 5 + local shoulderX, shoulderY = fielderX + 10, fielderY - 5 if distanceFromBall > 20 then Glove:draw(shoulderX, shoulderY) return false @@ -20,11 +17,12 @@ local function drawFielderGlove(ball, fielderX, fielderY) end end +---@param playerSprites SpriteCollection ---@param ball Point3d ---@param x number ---@param y number ---@return boolean isHoldingBall -function drawFielder(ball, x, y) - gfx.fillRect(x, y, 14, 25) +function drawFielder(playerSprites, ball, x, y) + playerSprites.smiling:draw(x, y - 20) return drawFielderGlove(ball, x, y) end diff --git a/src/draw/player.lua b/src/draw/player.lua new file mode 100644 index 0000000..4ded261 --- /dev/null +++ b/src/draw/player.lua @@ -0,0 +1,58 @@ +-- selene: allow(shadowing) +local gfx = playdate.graphics + +---@alias SpriteCollection { smiling: pd_image, lowHat: pd_image, frowning: pd_image, back: pd_image } + +---@param image pd_image +---@param drawInverted boolean +function maybeDrawInverted(image, x, y, drawInverted) + -- TODO: Bring logo up a pixel on the dark player base? + local drawMode = gfx.getImageDrawMode() + if drawInverted then + gfx.setImageDrawMode(gfx.kDrawModeInverted) + end + image:draw(x, y) + gfx.setImageDrawMode(drawMode) +end + +---@return SpriteCollection +---@param base pd_image +---@param isDark boolean +function buildCollection(base, back, logo, isDark) + local smiling = gfx.image.new(base:getSize()) + gfx.lockFocus(smiling) + base:draw(0, 0) + Hat:draw(6, 0) + PlayerSmile:draw(5, 9) + maybeDrawInverted(logo, 3, 25, isDark) + + local lowHat = gfx.image.new(base:getSize()) + gfx.lockFocus(lowHat) + base:draw(0, 0) + Hat:draw(6, 2) + PlayerSmile:draw(5, 9) + maybeDrawInverted(logo, 3, 25, isDark) + + local frowning = gfx.image.new(base:getSize()) + + gfx.lockFocus(frowning) + base:draw(0, 0) + maybeDrawInverted(logo, 3, 25, isDark) + Hat:draw(6, 0) + PlayerFrown:draw(5, 9) + + gfx.unlockFocus() + + return { + smiling = smiling, + lowHat = lowHat, + frowning = frowning, + back = back, + } +end + +--selene: allow(unscoped_variables) +AwayTeamSprites = buildCollection(DarkPlayerBase, DarkPlayerBack, BaseLogo, true) + +--selene: allow(unscoped_variables) +HomeTeamSprites = buildCollection(LightPlayerBase, LightPlayerBack, FrownLogo, false) diff --git a/src/fielding.lua b/src/fielding.lua index f199501..e11b6f7 100644 --- a/src/fielding.lua +++ b/src/fielding.lua @@ -156,12 +156,14 @@ function Fielding:celebrate() FielderDanceAnimator:reset(C.DanceBounceMs) end +---@param fielderSprites SpriteCollection ---@param ball Point3d ---@return boolean ballIsHeldByAFielder -function Fielding:drawFielders(ball) +function Fielding:drawFielders(fielderSprites, ball) local ballIsHeld = false + local danceOffset = FielderDanceAnimator:currentValue() for _, fielder in pairs(self.fielders) do - ballIsHeld = drawFielder(ball, fielder.x, fielder.y + FielderDanceAnimator:currentValue()) or ballIsHeld + ballIsHeld = drawFielder(fielderSprites, ball, fielder.x, fielder.y + danceOffset) or ballIsHeld end return ballIsHeld end diff --git a/src/graphics.lua b/src/graphics.lua index aa6e56f..9776473 100644 --- a/src/graphics.lua +++ b/src/graphics.lua @@ -25,20 +25,23 @@ blipper = {} --- 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. -function blipper.new(msInterval, image1, image2) +function blipper.new(msInterval, smiling, lowHat) local blinker = playdate.graphics.animation.blinker.new(msInterval, msInterval, true) blinker:start() return { blinker = blinker, - image1 = image1, - image2 = image2, + smiling = smiling, + lowHat = lowHat, draw = function(self, disableBlipping, x, y) - local currentImage = (disableBlipping or self.blinker.on) and self.image2 or self.image1 - local offsetY = currentImage == PlayerLowHat and -1 or 0 + local currentImage = (disableBlipping or self.blinker.on) and self.lowHat or self.smiling + local offsetY = currentImage == lowHat and -1 or 0 currentImage:draw(x, y + offsetY) end, } end --selene: allow(unscoped_variables) -PlayerImageBlipper = blipper.new(100, Player, PlayerLowHat) +HomeTeamBlipper = blipper.new(100, HomeTeamSprites.smiling, HomeTeamSprites.lowHat) + +--selene: allow(unscoped_variables) +AwayTeamBlipper = blipper.new(100, AwayTeamSprites.smiling, AwayTeamSprites.lowHat) diff --git a/src/images/game/BaseLogo.png b/src/images/game/BaseLogo.png new file mode 100644 index 0000000..28d1cdc Binary files /dev/null and b/src/images/game/BaseLogo.png differ diff --git a/src/images/game/PlayerLowHat.png b/src/images/game/DarkPlayerBack.png similarity index 73% rename from src/images/game/PlayerLowHat.png rename to src/images/game/DarkPlayerBack.png index 824caac..a9c3ebe 100644 Binary files a/src/images/game/PlayerLowHat.png and b/src/images/game/DarkPlayerBack.png differ diff --git a/src/images/game/DarkPlayerBase.png b/src/images/game/DarkPlayerBase.png new file mode 100644 index 0000000..c661f95 Binary files /dev/null and b/src/images/game/DarkPlayerBase.png differ diff --git a/src/images/game/FrownLogo.png b/src/images/game/FrownLogo.png new file mode 100644 index 0000000..e86fd9c Binary files /dev/null and b/src/images/game/FrownLogo.png differ diff --git a/src/images/game/Hat.png b/src/images/game/Hat.png new file mode 100644 index 0000000..512fd5c Binary files /dev/null and b/src/images/game/Hat.png differ diff --git a/src/images/game/PlayerBack.png b/src/images/game/LightPlayerBack.png similarity index 100% rename from src/images/game/PlayerBack.png rename to src/images/game/LightPlayerBack.png diff --git a/src/images/game/Player.png b/src/images/game/LightPlayerBase.png similarity index 80% rename from src/images/game/Player.png rename to src/images/game/LightPlayerBase.png index 22db89b..a36931f 100644 Binary files a/src/images/game/Player.png and b/src/images/game/LightPlayerBase.png differ diff --git a/src/images/game/PlayerFrown.png b/src/images/game/PlayerFrown.png index c213f62..3ca982c 100644 Binary files a/src/images/game/PlayerFrown.png and b/src/images/game/PlayerFrown.png differ diff --git a/src/images/game/PlayerSmile.png b/src/images/game/PlayerSmile.png new file mode 100644 index 0000000..b6e9f82 Binary files /dev/null and b/src/images/game/PlayerSmile.png differ diff --git a/src/main.lua b/src/main.lua index 6abced1..89e5eb2 100644 --- a/src/main.lua +++ b/src/main.lua @@ -23,6 +23,7 @@ import 'CoreLibs/ui.lua' import 'utils.lua' import 'constants.lua' import 'assets.lua' +import 'draw/player.lua' import 'draw/overlay.lua' import 'draw/fielder.lua' @@ -64,6 +65,9 @@ local teams = { local UserTeam = teams.away local battingTeam = teams.away +local battingTeamSprites = AwayTeamSprites +local fieldingTeamSprites = HomeTeamSprites +local runnerBlipper = battingTeam == teams.away and AwayTeamBlipper or HomeTeamBlipper local inning = 1 local offenseState = C.Offense.batting @@ -174,6 +178,15 @@ local function nextHalfInning() -- Delay to keep end-of-inning on the scoreboard for a few seconds playdate.timer.new(3000, function() battingTeam = currentlyFieldingTeam + if battingTeam == teams.home then + battingTeamSprites = HomeTeamSprites + runnerBlipper = HomeTeamBlipper + fieldingTeamSprites = AwayTeamSprites + else + battingTeamSprites = AwayTeamSprites + fieldingTeamSprites = HomeTeamSprites + runnerBlipper = AwayTeamBlipper + end if gameOver then announcer:say("AND THAT'S THE BALL GAME!") else @@ -279,6 +292,7 @@ local function updateBatting(batDeg, batSpeed) pitchTracker:reset() local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill) launchBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler) + -- TODO? A dramatic eye-level view on a home-run could be sick. if utils.isFoulBall(ballDestX, ballDestY) then announcer:say("Foul ball!") @@ -451,7 +465,7 @@ function playdate.update() GrassBackground:draw(-400, -240) - local ballIsHeld = fielding:drawFielders(ball) + local ballIsHeld = fielding:drawFielders(fieldingTeamSprites, ball) if offenseState == C.Offense.batting then gfx.setLineWidth(5) @@ -463,18 +477,18 @@ function playdate.update() for _, runner in pairs(baserunning.runners) do if runner == baserunning.batter then if batAngleDeg > 50 and batAngleDeg < 200 then - PlayerBack:draw(runner.x, runner.y - playerHeightOffset) + battingTeamSprites.back:draw(runner.x, runner.y - playerHeightOffset) else - Player:draw(runner.x, runner.y - playerHeightOffset) + battingTeamSprites.smiling:draw(runner.x, runner.y - playerHeightOffset) end else -- TODO? Change blip speed depending on runner speed? - PlayerImageBlipper:draw(false, runner.x, runner.y - playerHeightOffset) + runnerBlipper:draw(false, runner.x, runner.y - playerHeightOffset) end end for _, runner in pairs(baserunning.outRunners) do - PlayerFrown:draw(runner.x, runner.y - playerHeightOffset) + battingTeamSprites.frowning:draw(runner.x, runner.y - playerHeightOffset) end if not ballIsHeld then