diff --git a/.luarc.json b/.luarc.json index 470ffe1..07d83c5 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,22 +1,34 @@ { - "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", - "diagnostics.globals": ["import"], - "diagnostics.severity": { - "duplicate-set-field": "Hint" - }, - "format.defaultConfig": { - "indent_style": "space", - "indent_size": "4" - }, - "runtime.builtin": { - "io": "disable", - "os": "disable", - "package": "disable" - }, - "runtime.nonstandardSymbol": ["+=", "-=", "*=", "/=", "//=", "%=", "<<=", ">>=", "&=", "|=", "^="], - "runtime.version": "Lua 5.4", - "workspace.library": [ - "/home/ut3usw/src/playdate-luacats" - "/home/ut3usw/Projects/VSCode-PlaydateTemplate/source/libraries" - ] + "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", + "diagnostics.globals": ["import"], + "diagnostics.severity": { + "duplicate-set-field": "Hint" + }, + "format.defaultConfig": { + "indent_style": "space", + "indent_size": "4" + }, + "runtime.builtin": { + "io": "disable", + "os": "disable", + "package": "disable" + }, + "runtime.nonstandardSymbol": [ + "+=", + "-=", + "*=", + "/=", + "//=", + "%=", + "<<=", + ">>=", + "&=", + "|=", + "^=" + ], + "runtime.version": "Lua 5.4", + "workspace.library": [ + "/home/ut3usw/src/playdate-luacats", + "/home/ut3usw/Projects/VSCode-PlaydateTemplate/source/libraries" + ] } diff --git a/README.md b/README.md index bad0f1d..b25c4eb 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ # FPV Run + +## TODO: + +- [ ] Menu audio +- [ ] Tags, zOffset from constants +- [ ] Add global game state (?) diff --git a/source/assets/sprites/baleba-table-64-64.png b/source/assets/sprites/baleba-table-64-64.png index 4a86467..dd5d4d6 100644 Binary files a/source/assets/sprites/baleba-table-64-64.png and b/source/assets/sprites/baleba-table-64-64.png differ diff --git a/source/assets/sprites/bigboom-table-400-240.png b/source/assets/sprites/bigboom-table-400-240.png new file mode 100644 index 0000000..611c8e3 Binary files /dev/null and b/source/assets/sprites/bigboom-table-400-240.png differ diff --git a/source/assets/sprites/oldbaleba-table-64-64.png b/source/assets/sprites/oldbaleba-table-64-64.png new file mode 100644 index 0000000..4a86467 Binary files /dev/null and b/source/assets/sprites/oldbaleba-table-64-64.png differ diff --git a/source/libraries/noble/modules/Noble.Animation.lua b/source/libraries/noble/modules/Noble.Animation.lua index 4eafb8c..02744ec 100644 --- a/source/libraries/noble/modules/Noble.Animation.lua +++ b/source/libraries/noble/modules/Noble.Animation.lua @@ -49,7 +49,6 @@ Noble.Animation = {} -- end -- @see NobleSprite:init function Noble.Animation.new(__view) - local animation = {} --- Properties @@ -117,11 +116,10 @@ function Noble.Animation.new(__view) -- animation.["jump"].next -- "float" -- animation.idle.next -- nil function animation:addState(__name, __startFrame, __endFrame, __next, __loop, __onComplete, __frameDuration) - local loop = true local frameDuration = 1 if (__loop ~= nil) then loop = __loop end - if(__frameDuration ~= nil) then frameDuration = __frameDuration end + if (__frameDuration ~= nil) then frameDuration = __frameDuration end self[__name] = { name = __name, startFrame = __startFrame, @@ -140,7 +138,6 @@ function Noble.Animation.new(__view) self.currentName = __name self.frameDuration = frameDuration end - end --- Methods @@ -180,7 +177,6 @@ function Noble.Animation.new(__view) -- groundedLastFrame = grounded -- end function animation:setState(__animationState, __continuous, __unlessThisState) - if (__unlessThisState ~= nil) then if (type(__unlessThisState) == "string") then if (self.currentName == __unlessThisState) then return end @@ -228,25 +224,26 @@ function Noble.Animation.new(__view) -- animation:draw(100,100) -- end function animation:draw(__x, __y, __advance) - --print(self.currentName .. " > " .. self.currentFrame .. " >> " .. tostring(self.current.loop)) if (__advance == nil) then __advance = true end - if(self.currentFrame < self.current.startFrame or self.currentFrame > self.current.endFrame + 1) then - self.currentFrame = self.current.startFrame -- Error correction. - elseif(self.currentFrame == self.current.endFrame + 1) then -- End frame behavior. + if (self.currentFrame < self.current.startFrame or self.currentFrame > self.current.endFrame + 1) then + self.currentFrame = self.current.startFrame -- Error correction. + elseif (self.currentFrame == self.current.endFrame + 1) then -- End frame behavior. if (self.current.next ~= nil) then - self.currentFrame = self.current.next.startFrame -- Set to first frame of next animation. - self.frameDurationCount = 1 -- Reset ticks. + self.currentFrame = self.current.next.startFrame -- Set to first frame of next animation. + self.frameDurationCount = 1 -- Reset ticks. self.previousFrameDurationCount = self.frameDuration - self:setState(self.current.next) -- Set next animation state. + self:setState(self.current.next) -- Set next animation state. elseif (self.current.loop == true) then - self.currentFrame = self.current.startFrame -- Loop animation state. (TO-DO: account for continuous somehow?) - self.frameDurationCount = 1 -- Reset ticks. + self.currentFrame = self.current + .startFrame -- Loop animation state. (TO-DO: account for continuous somehow?) + self.frameDurationCount = 1 -- Reset ticks. self.previousFrameDurationCount = self.frameDuration - elseif(__advance) then - self.currentFrame = self.currentFrame - 1 -- Undo advance frame because we want to draw the same frame again. + elseif (__advance) then + self.currentFrame = self.currentFrame - + 1 -- Undo advance frame because we want to draw the same frame again. end if (self.current.onComplete ~= nil) then @@ -260,7 +257,7 @@ function Noble.Animation.new(__view) if (__advance == true) then self.frameDurationCount += 1 - if((self.frameDurationCount - self.previousFrameDurationCount) >= self.current.frameDuration) then + if ((self.frameDurationCount - self.previousFrameDurationCount) >= self.current.frameDuration) then self.currentFrame = self.currentFrame + 1 self.previousFrameDurationCount += self.current.frameDuration end diff --git a/source/libraries/noble/modules/NobleSprite.lua b/source/libraries/noble/modules/NobleSprite.lua index d04d69f..aad6d31 100644 --- a/source/libraries/noble/modules/NobleSprite.lua +++ b/source/libraries/noble/modules/NobleSprite.lua @@ -56,9 +56,7 @@ class("NobleSprite").extends(Graphics.sprite) function NobleSprite:init(__view, __viewIsSpritesheet, __singleState, __singleStateLoop) NobleSprite.super.init(self) self.isNobleSprite = true -- This is important so other methods don't confuse this for a playdate.graphics.sprite. DO NOT modify this value at runtime. - if (__view ~= nil) then - -- __view is the path to an image or spritesheet file. if (type(__view) == "string") then self.animated = __viewIsSpritesheet -- NO NOT modify self.animated at runtime. @@ -76,25 +74,22 @@ function NobleSprite:init(__view, __viewIsSpritesheet, __singleState, __singleSt if (__singleState == true) then self.animation:addState("default", 1, self.animation.imageTable:getLength(), nil, singleStateLoop) end - else -- Create a new Graphics.image object. self:setImage(Graphics.image.new(__view)) end - -- __view is an existing Graphics.image object. + -- __view is an existing Graphics.image object. elseif (type(__view) == "userdata") then self.animated = false self:setImage(__view) - -- __view is an existing Noble.Animation object. + -- __view is an existing Noble.Animation object. elseif (type(__view) == "table") then self.animated = true self.animation = __view end - end - end function NobleSprite:draw() @@ -144,11 +139,11 @@ end function NobleSprite:remove() if (self.animation ~= nil) then self:stop() - self:setUpdatesEnabled(true) -- reset! + self:setUpdatesEnabled(true) -- reset! end Noble.currentScene():removeSprite(self) end function NobleSprite:superRemove() NobleSprite.super.remove(self) -end \ No newline at end of file +end diff --git a/source/main.lua b/source/main.lua index f14df0d..9743d86 100644 --- a/source/main.lua +++ b/source/main.lua @@ -13,7 +13,24 @@ import "libraries/playout" import 'utilities/enum' import 'utilities/ui' +ZIndex = { + player = 4, + enemy = 3, + props = 3, + fx = 6, + ui = 10, + alert = 12 +} +CollideGroups = { + player = 1, + enemy = 2, + props = 3, + items = 4, + wall = 5 +} + import "scripts/player" +import "scripts/bigBoomSprite" import "scripts/groundSprite" import "scripts/balebaSprite" import "scripts/dangerSprite" @@ -24,7 +41,7 @@ import 'scenes/Menu' import 'scenes/Game' Noble.Settings.setup({ - difficulty = "Medium", + difficulty = "Medium", music = true }) @@ -36,4 +53,4 @@ playdate.display.setRefreshRate(50) Noble.showFPS = true -Noble.new(Game) \ No newline at end of file +Noble.new(Game) diff --git a/source/scenes/Game.lua b/source/scenes/Game.lua index 101ef0f..ffed0fe 100644 --- a/source/scenes/Game.lua +++ b/source/scenes/Game.lua @@ -20,142 +20,117 @@ end function scene:setValues() scene.background = Graphics.image.new("assets/sprites/bg") - scene.telemLostSound = playdate.sound.fileplayer.new( "assets/audio/telemko" ) + scene.telemLostSound = playdate.sound.fileplayer.new("assets/audio/telemko") scene.telemLostSoundPlayed = false + scene.resultShowed = false + + scene.musicEnabled = Noble.Settings.get("music") + scene.balebas = {} - scene.t = playdate.timer.new(10000) - scene.t.repeats = true - - scene.tankTimer = playdate.timer.new(1000) - - scene.fp = playdate.sound.fileplayer.new( "assets/audio/war" ) - scene.fp:setVolume(0.7) - scene.hello = playdate.sound.fileplayer.new( "assets/audio/hello" ) + scene.balebaSpawner = playdate.timer.new(10000) + scene.balebaSpawner.repeats = true + scene.levelAudio = playdate.sound.fileplayer.new("assets/audio/war") + scene.levelAudio:setVolume(0.7) + scene.helloAudio = playdate.sound.fileplayer.new("assets/audio/hello") end function scene:init() - scene.super.init(self) - scene:setValues() + scene.super.init(self) + scene:setValues() end function scene:start() scene.super.start(self) self.optionsMenu:addMenuItem("Main Menu", function() Noble.transition(Menu) end) - Noble.showFPS = true + Noble.showFPS = true end function scene:spawnBaleba() - local baleba = Baleba(math.random(410, 900), math.random(10, 210), scene.player, true) - baleba:add() + local balebaCount = #scene.balebas + if balebaCount >= 6 then + return + end - return baleba + scene.balebas[balebaCount + 1] = Baleba(math.random(410, 900), math.random(10, 210), scene.player, true) + + return scene.balebas[balebaCount + 1] end function scene:enter() - scene.super.enter(self) + scene.super.enter(self) - scene.player = Player(30, 30) - scene.player:add() - - scene.ground = Ground(400, 225, scene.player) - scene.ground:add() + scene.player = Player(150, 100) + scene.ground = Ground(0, 225, scene.player) - scene.t.timerEndedCallback = function() - if #scene.balebas >= 6 then - return - end - - local k = #scene.balebas+1 + scene.balebaSpawner.timerEndedCallback = function() --scene.balebas[k] = scene:spawnBaleba() end - for i=1, 3 do - scene.balebas[i] = scene:spawnBaleba() + for i = 1, 3 do + scene:spawnBaleba() end - local musicEnabled = Noble.Settings.get("music") - scene.hello:play(1) - if musicEnabled then - scene.fp:play(0) + scene.helloAudio:play(1) + if scene.musicEnabled then + scene.levelAudio:play(0) end - scene.tankTimer.timerEndedCallback = function() + playdate.timer.performAfterDelay(1000, function() scene.tank = Tank(550, 190, scene.player, scene.ground) - scene.tank:add() - end + scene:addSprite(scene.tank) -- Raw sprite + end) end function scene:update() - scene.super.update(self) + scene.super.update(self) if scene.player == nil then - Noble.Text.draw("Telemetry Lost", 200, 110, Noble.Text.ALIGN_CENTER, false, font) return end - if scene.player.isDead() and not scene.telemLostSoundPlayed then + if scene.player.isDead() then + if scene.resultShowed ~= true then + Noble.Text.draw("Telemetry Lost", 200, 110, Noble.Text.ALIGN_CENTER, false, font) + end + else + Noble.Text.draw("Bat: " .. math.floor(scene.player.getBat() / 100), 10, 215, Noble.Text.ALIGN_LEFT, false, font) + end + + if scene.player.isDead() and not scene.telemLostSoundPlayed then scene.telemLostSound:play(1) scene.telemLostSoundPlayed = true - screenShake(500, 5) - + screenShake(1000, 5) + + playdate.timer.performAfterDelay(4000, function() + scene.resultShowed = true + c = notify("Nice", function() + Noble.transition(Menu) + c:remove() + end) + c:moveTo(200, 120) + c:add() + end) - local et = playdate.timer.new(6000) - et.timerEndedCallback = function() - Noble.transition(Menu) - end return - end - - local bat = scene.player.getBat() - bat = math.floor(bat/100) - Noble.Text.draw("Bat: " .. bat, 10, 215, Noble.Text.ALIGN_LEFT, false, font) - -end - -function scene:destroyPlayer() - if scene.player ~= nil then - scene.player:remove() - scene.player = nil end end function scene:exit() scene.super.exit(self) - scene:destroyPlayer() - - scene.ground:remove() - scene.ground = nil - scene.tank:remove() - scene.ground = nil - - for i=1, #scene.balebas do - scene.balebas[i]:destroy() - scene.balebas[i] = nil - end - scene.telemLostSound:stop() - scene.telemLostSoundPlayed = false + scene.levelAudio:stop() + scene.balebaSpawner:remove() - scene.fp:stop() - - scene.t:remove() - scene.t = nil - - scene.tankTimer:remove() - scene.tankTimer = nil - - - Noble.showFPS = false + Noble.showFPS = false end - function scene:finish() - scene.super.finish(self) - playdate.display.setScale(1) -end \ No newline at end of file + scene.super.finish(self) + playdate.display.setScale(1) +end diff --git a/source/scripts/balebaSprite.lua b/source/scripts/balebaSprite.lua index e8193be..7d85795 100644 --- a/source/scripts/balebaSprite.lua +++ b/source/scripts/balebaSprite.lua @@ -1,24 +1,24 @@ Baleba = {} -class('Baleba').extends(AnimatedSprite) +class('Baleba').extends(NobleSprite) function randomFloat(lower, greater) - return lower + math.random() * (greater - lower); + return lower + math.random() * (greater - lower); end -local balebaImageTable = Graphics.imagetable.new("assets/sprites/baleba") - function Baleba:init(x, y, player, loop) - Baleba.super.init(self, balebaImageTable) + Baleba.super.init(self, "assets/sprites/baleba", true) -- Animation properties - self:addState("run", 1,4, {tickStep = 2}) - self:setDefaultState("run") - self:playAnimation() + self.animation:addState("run", 1, 4) + self.animation.run.frameDuration = 2 + + self.animation:setState("run") -- Collision properties self:setZIndex(11) self:setCollideRect(3, 25, 40, 15) self:setTag(154) + self:setSize(64, 64) -- Sprite properties self.standrate = randomFloat(0.3, 2) @@ -28,15 +28,13 @@ function Baleba:init(x, y, player, loop) -- Danger properties self.danger = Danger(366, y, self) - self.danger:add() + self:add() -- Move to initial position self:moveTo(x, y) end function Baleba:update() - self:updateAnimation() - -- Speedup when player is moving right if self.player == nil or self.player.isMovingRight() == false then self.xVelocity = self.standrate @@ -44,7 +42,7 @@ function Baleba:update() self.xVelocity = 2 + self.standrate end - self:moveTo(self.x-self.xVelocity, self.y) + self:moveTo(self.x - self.xVelocity, self.y) -- Danger arrow management if self.x < 430 and self.danger ~= nil then @@ -52,7 +50,6 @@ function Baleba:update() self.danger = nil elseif self.danger == nil and self.x > 430 then self.danger = Danger(366, self.y, self) - self.danger:add() end -- Lifeciycle management @@ -69,4 +66,4 @@ function Baleba:destroy() self.danger:remove() end self:remove() -end \ No newline at end of file +end diff --git a/source/scripts/bigBoomSprite.lua b/source/scripts/bigBoomSprite.lua new file mode 100644 index 0000000..e18a3d4 --- /dev/null +++ b/source/scripts/bigBoomSprite.lua @@ -0,0 +1,28 @@ +BigBoom = {} +class("BigBoom").extends(AnimatedSprite) + +local bigBoomImageTable = Graphics.imagetable.new("assets/sprites/bigboom") + +function BigBoom:init() + BigBoom.super.init(self, bigBoomImageTable) + + -- Animation properties + self:addState("play", 1, 3, { tickStep = 4, loop = 3 }) + self:setDefaultState("play") + self:playAnimation() + self:setCenter(0, 0) + self:setSize(playdate.display.getSize()) + self:setZIndex(120) + + self:moveTo(0, 0) + + self:add() +end + +function BigBoom:update() + self:updateAnimation() +end + +function BigBoom:stopAnimation() + self:remove() +end diff --git a/source/scripts/dangerSprite.lua b/source/scripts/dangerSprite.lua index 8032bf0..9721ed0 100644 --- a/source/scripts/dangerSprite.lua +++ b/source/scripts/dangerSprite.lua @@ -1,24 +1,21 @@ Danger = {} -class("Danger").extends(AnimatedSprite) - -local dangerImageTable = Graphics.imagetable.new("assets/sprites/danger") +class("Danger").extends(NobleSprite) function Danger:init(x, y, dangerousObject) - Danger.super.init(self, dangerImageTable) + Danger.super.init(self, "assets/sprites/danger", true) self.dangerousObject = dangerousObject -- Animation properties - self:addState("run", 1,5, {tickStep = 2}) - self:setDefaultState("run") - self:playAnimation() + self.animation:addState("run", 1, 5) + self.animation.run.frameDuration = 2 + + self.animation:setState("run") -- Collision properties self:setZIndex(11) self:setTag(7) + self:setSize(64, 64) + self:add() self:moveTo(x, y) end - -function Danger:update() - self:updateAnimation() -end \ No newline at end of file diff --git a/source/scripts/groundSprite.lua b/source/scripts/groundSprite.lua index 998a0f5..07f4749 100644 --- a/source/scripts/groundSprite.lua +++ b/source/scripts/groundSprite.lua @@ -1,21 +1,20 @@ Ground = {} -class("Ground").extends(Graphics.sprite) - -local groundImage = Graphics.image.new("assets/sprites/groundFin") +class("Ground").extends(NobleSprite) function Ground:init(x, y, player) - Ground.super.init(self, groundImage) - + Ground.super.init(self, "assets/sprites/groundFin") + -- Collision properties self:setZIndex(100) self:setTag(3) self:setCollideRect(0, 28, 800, 10) + self:setSize(800, 32) -- Main properties Ground.moveSpeed = 2 Ground.player = player - -- Move to initial position + self:add() self:moveTo(x, y) end @@ -24,7 +23,6 @@ function Ground:setMoveSpeed(speed) end function Ground:update() - -- Stop ground if Ground.moveSpeed == 0 then return @@ -43,5 +41,5 @@ function Ground:update() end -- Move ground - self:moveWithCollisions(self.x-Ground.moveSpeed, self.y) -end \ No newline at end of file + self:moveWithCollisions(self.x - Ground.moveSpeed, self.y) +end diff --git a/source/scripts/player.lua b/source/scripts/player.lua index fd81b1e..9692ce0 100644 --- a/source/scripts/player.lua +++ b/source/scripts/player.lua @@ -1,20 +1,26 @@ Player = {} -class("Player").extends(AnimatedSprite) - -local playerImageTable = Graphics.imagetable.new("assets/sprites/player") +class("Player").extends(NobleSprite) function Player:init(x, y) - Player.super.init(self, playerImageTable) + Player.super.init(self, "assets/sprites/player", true) -- Animation properties - self:addState("run", 1, 7, { tickStep = 2 }) - self:addState("up", 1, 7, { tickStep = 6 }) - self:addState("down", 1, 7, { tickStep = 6 }) - self:addState("boom", 15, 21, { tickStep = 10, loop = false }) - self:setDefaultState("down") - self:playAnimation() + self.animation:addState("run", 1, 7) + self.animation.run.frameDuration = 2 + self.animation:addState("up", 1, 7) + self.animation.up.frameDuration = 6 + self.animation:addState("down", 1, 7) + self.animation.down.frameDuration = 6 + self.animation:addState("boom", 15, 21) + self.animation.boom.frameDuration = 10 + self.animation.boom.loop = false + + self.animation:setState("down") + + self:add() -- Collision properties + self:setSize(64, 64) self:moveTo(x, y) self:setZIndex(10) self:setCollideRect(3, 19, 63, 33) @@ -65,9 +71,9 @@ function Player:handleInput() if crankChange ~= 0 then local force = 0.01 if crankChange > 0 then - self:changeState("up") + self.animation:setState("up") else - self:changeState("down") + self.animation:setState("down") force = 0.05 end self.yVelocity = self.yVelocity - acceleratedChange * force @@ -83,25 +89,25 @@ function Player:changeToDownState() Player.moveRight = false self.yVelocity = self.fallSpeed self.xVelocity = 0 - self:changeState("down") + self.animation:setState("down") self:setRotation(0) end function Player:changeToRunState(direction) if direction == "left" then self.xVelocity = -self.maxXSpeed - self.globalFlip = 1 - self:changeState("run") + self.animation.direction = Noble.Animation.DIRECTION_LEFT + self.animation:setState("run") elseif direction == "right" then self.xVelocity = self.maxXSpeed - self.globalFlip = 0 - self:changeState("run") + self.animation.direction = Noble.Animation.DIRECTION_RIGHT + self.animation:setState("run") end end function Player:boom(collisionObject) Player.dead = true - self:changeState("boom") + self.animation:setState("boom") local particleB = ParticlePoly(self.x, self.y) particleB:setThickness(2) @@ -159,11 +165,12 @@ function Player:handleMovementAndCollisions() return elseif collisionTag == 2 then -- Tank self:boom() + BigBoom() local particleC = ParticlePoly(collisionObject.x, collisionObject.y) particleC:setThickness(5) particleC:setAngular(-15, 15) - particleC:setSize(1, 5) + particleC:setSize(1, 10) particleC:setSpeed(1, 3) particleC:setMode(Particles.modes.STAY) particleC:setBounds(0, 0, 400, 240) @@ -207,16 +214,13 @@ function Player:handleDischarge(state) end function Player:update() - self:updateAnimation() self:handleMovementAndCollisions() - if Player.dead then + print("Player is dead") return end - local state = self:getCurrentState()["name"] - - self:handleDischarge(state) + self:handleDischarge(self.animation.currentName) self:handleInput() end diff --git a/source/scripts/tankSprite.lua b/source/scripts/tankSprite.lua index 6440e5f..de51216 100644 --- a/source/scripts/tankSprite.lua +++ b/source/scripts/tankSprite.lua @@ -13,7 +13,7 @@ function Tank:init(x, y, player, ground) Graphics.pushContext(self.faded_image) self.tankImageD:drawBlurred(0, 0, 2, 2, Graphics.image.kDitherTypeFloydSteinberg) - Graphics.popContext() + Graphics.popContext() -- Collision properties self:setZIndex(99) @@ -51,5 +51,5 @@ function Tank:update() Tank.moveSpeed = 1 end - self:moveTo(self.x-Tank.moveSpeed, self.y) + self:moveTo(self.x - Tank.moveSpeed, self.y) end