BomberScene = {} class("BomberScene").extends(BaseScene) local scene = BomberScene local font = Graphics.font.new('assets/fonts/Mini Sans 2X') function scene:init() scene.super.init(self) self.bg = Graphics.image.new("assets/sprites/bg2") self.bgY = 0 self.scrollSpeed = 0.6 scene.dropSound = playdate.sound.fileplayer.new("assets/audio/drop1") scene.themeSound = playdate.sound.fileplayer.new("assets/audio/bomberTheme") scene.themeSound:setVolume(0.5) scene.themeSound:play() scene.progressBar = ProgressBar(50, 210, 50, 5) scene.progressBar:set(0) scene.progressBar:setVisible(false) scene.grenadeCooldown = false scene.grenadeCooldownTimer = nil scene.grenadeCooldownDuration = 100 scene.progressBarMax = 100 scene.autoReload = false scene.reloadProgress = 0 scene.crankSensitivity = 0.2 scene.availableGrenades = 8 scene.enemies = {} scene.enemySpawnTimer = nil scene.enemySpawnInterval = 1000 scene.maxEnemies = 5 scene.nextEnemyIndex = 1 scene.minSpawnDelay = 500 scene.maxSpawnDelay = 3500 BomberScene.instance = self end function scene:drawBackground() self.bgY = self.bgY + self.scrollSpeed if self.bgY >= 720 then self.bgY = 0 end self.bg:draw(0, self.bgY - 720) self.bg:draw(0, self.bgY) end scene.inputHandler = { upButtonHold = function() scene.crosshair:moveUp() end, downButtonHold = function() scene.crosshair:moveDown() end, leftButtonHold = function() scene.crosshair:moveLeft() end, rightButtonHold = function() scene.crosshair:moveRight() end, AButtonDown = function() if scene.availableGrenades <= 0 then return end print("AButtonDown") if not scene.grenadeCooldown then Granade(scene.crosshair.x, scene.crosshair.y) scene.grenadeCooldown = true scene.progressBar:set(0) scene.progressBar:setVisible(true) scene.availableGrenades = scene.availableGrenades - 1 scene.dropSound:play() if scene.autoReload then scene.grenadeCooldownTimer = playdate.timer.new(scene.grenadeCooldownDuration, function() scene.grenadeCooldown = false scene.progressBar:setVisible(false) end) scene.grenadeCooldownTimer.updateCallback = function(timer) local percentage = (scene.grenadeCooldownDuration - timer.timeLeft) / scene.grenadeCooldownDuration * scene.progressBarMax scene.progressBar:set(percentage) end else scene.reloadProgress = 0 end end end } function scene:enter() scene.super.enter(self) Noble.Input.setHandler(scene.inputHandler) scene.crosshair = MovableCrosshair(100, 100) scene:scheduleNextEnemySpawn() NoiseAnimation(200, 120) end function scene:start() scene.super.start(self) self.optionsMenu:addMenuItem("Main Menu", function() Noble.transition(Menu) end) Noble.showFPS = true end function scene:update() scene.super.update(self) if scene.grenadeCooldown and not scene.autoReload and not playdate.isCrankDocked() then local change = playdate.getCrankChange() if change > 0 or change < 0 then scene.reloadProgress = scene.reloadProgress + (change * scene.crankSensitivity) if scene.reloadProgress > scene.progressBarMax then scene.reloadProgress = scene.progressBarMax scene.grenadeCooldown = false scene.progressBar:setVisible(false) end scene.progressBar:set(scene.reloadProgress) end end Noble.Text.draw(scene.availableGrenades .. "x", 10, 210, Noble.Text.ALIGN_LEFT, false, font) if scene.availableGrenades <= 0 then Noble.Text.draw("No grenades left", 200, 110, Noble.Text.ALIGN_CENTER, false, font) scene.crosshair:setVisible(false) scene.progressBar:setVisible(false) elseif playdate.isCrankDocked() then Noble.Text.draw("Crank it to reload!", 200, 110, Noble.Text.ALIGN_CENTER, false, font) playdate.ui.crankIndicator:draw() end end function scene:spawnEnemies() local activeEnemies = 0 for i = 1, #scene.enemies do if scene.enemies[i] and not scene.enemies[i].removed then activeEnemies = activeEnemies + 1 end end if activeEnemies < self.maxEnemies then scene.enemies[scene.nextEnemyIndex] = Enemy(math.random(30, 370), -20) scene.nextEnemyIndex = scene.nextEnemyIndex + 1 end scene:scheduleNextEnemySpawn() end function scene:scheduleNextEnemySpawn() local delay = math.random(scene.minSpawnDelay, scene.maxSpawnDelay) scene.enemySpawnTimer = playdate.timer.new(delay, function() scene:spawnEnemies() end) end function scene:finish() scene.themeSound:stop() scene.enemySpawnTimer:remove() for i = 1, #scene.enemies do if scene.enemies[i] then scene.enemies[i]:remove() end end scene.enemies = {} if scene.progressBar then scene.progressBar:remove() end scene.progressBar = nil if scene.grenadeCooldownTimer then scene.grenadeCooldownTimer:remove() end scene.grenadeCooldownTimer = nil scene.crosshair:remove() scene.crosshair = nil BomberScene.instance = nil end -- TODO: random spawn some decorations -- TODO: add clouds or smoke -- TODO: random disactivate granades