From b8c826d7073b17845ed266d6271d4a0f976d1411 Mon Sep 17 00:00:00 2001 From: RafaelWO <38643099+RafaelWO@users.noreply.github.com> Date: Mon, 20 Dec 2021 18:43:02 +0100 Subject: [PATCH] Change/love 11.3 (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⬆️ Upgrade to LÖVE 11.3 * ⬆️ Upgrade to push v0.4 * 👽️ Change color values to be in the range of 0-1 * 👽️ Adapt to removals/deprecations from LÖVE 11.3 * 🔥 Remove code for debugging * 🐛 Fix health alarm resume after pause * 📝 Update README with new love2d version * 🔥 Remove old explosion sound --- README.md | 23 +- conf.lua | 17 +- lib/push.lua | 406 +++++++++++++++----------- main.lua | 6 +- sounds/explosion.wav | Bin 86796 -> 0 bytes src/Dependencies.lua | 52 ++-- src/Utils.lua | 18 +- src/constants.lua | 2 +- src/entity/Entity.lua | 1 - src/entity/Player.lua | 1 - src/entity/Ufo.lua | 1 - src/gui/LowHealthOverlay.lua | 2 +- src/gui/Menu.lua | 8 +- src/gui/PlayerHealthBar.lua | 8 +- src/gui/ProgressBar.lua | 12 +- src/object/GameObject.lua | 14 +- src/states/entity/EntityBaseState.lua | 10 +- src/states/game/GameOverState.lua | 2 +- src/states/game/HighscoreState.lua | 4 +- src/states/game/PauseState.lua | 4 +- src/states/game/PlayState.lua | 8 +- src/states/game/SelectShipState.lua | 7 +- src/states/game/StartState.lua | 3 +- src/world/Level.lua | 16 +- 24 files changed, 347 insertions(+), 278 deletions(-) delete mode 100644 sounds/explosion.wav diff --git a/README.md b/README.md index cdd5e0d..95540d6 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ GitHub all releases - - Love2d version + + Love2d version

@@ -21,24 +21,12 @@ Download the latest version of the game via the [releases][]. ### Windows and MacOS For Windows (win32, win64) and MacOS users, please download the corresponding `.zip` file. -If you have installed LÖVE or want to install it - for this, install the corresponding [release 0.10.2 from GitHub](https://github.com/love2d/love/releases/tag/0.10.2) - you can simply download the `.love` file from the [releases][] and double-click the file to start the game. +If you have installed LÖVE or want to install it (see the [official website](https://love2d.org/) for installing it) you can simply download the `.love` file from the [releases][] and double-click the file to start the game. ### Linux -To run the game on Linux you have to install LÖVE 0.10.2. You can do this manually using the link above or run the following commands in a terminal. - -```bash -LOVE_URL='https://github.com/love2d/love/releases/download/0.10.2' -TEMP_DEB1="$(mktemp)" -TEMP_DEB2="$(mktemp)" -wget -O "$TEMP_DEB1" "$LOVE_URL/liblove0_0.10.2ppa1_amd64.deb" -wget -O "$TEMP_DEB2" "$LOVE_URL/love_0.10.2ppa1_amd64.deb" -sudo dpkg -i "$TEMP_DEB1" "$TEMP_DEB2" -rm -f "$TEMP_DEB1" "$TEMP_DEB2" -``` - +To run the game on Linux you have to install LÖVE 11.3 from the [official website](https://love2d.org/). Then download the `.love` file from the [releases][] and simply double-click it. - ## Instructions #### Menu Use the arrow keys to navigate within menus and press enter to select. @@ -52,7 +40,7 @@ Press esc to quit. ## Used Libraries, Art Packs, Sounds ### Art Pack -The sprites (plus backgrounds, fonts and some sound effects) used in this game are from the art pack [Space Shooter Redux](https://opengameart.org/content/space-shooter-redux) by [Kenny](www.kenney.nl). +The sprites (plus backgrounds, fonts and some sound effects) used in this game are from the art pack [Space Shooter Redux](https://opengameart.org/content/space-shooter-redux) by [Kenny](https://www.kenney.nl). Some UI elements are from the [UI Pack: RPG Expansion](https://www.kenney.nl/assets/ui-pack-rpg-expansion) by Kenny. @@ -62,7 +50,6 @@ The soundtracks are from Juhani Junkala and can be found [here](https://opengame Other sound effects: - Various sounds from [512 Sound Effects](https://opengameart.org/content/512-sound-effects-8-bit-style) -- [Explosion](https://opengameart.org/content/explosion-0) ### Libraries * [Class](https://github.com/vrld/hump) diff --git a/conf.lua b/conf.lua index 137334b..9a6d034 100644 --- a/conf.lua +++ b/conf.lua @@ -1,10 +1,14 @@ function love.conf(t) t.identity = "space-love" -- The name of the save directory (string) - t.version = "0.10.2" -- The LÖVE version this game was made for (string) + t.appendidentity = false -- Search files in source directory before save directory (boolean) + t.version = "11.3" -- The LÖVE version this game was made for (string) t.console = false -- Attach a console (boolean, Windows only) t.accelerometerjoystick = false -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean) t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean) - t.gammacorrect = true -- Enable gamma-correct rendering, when supported by the system (boolean) + t.gammacorrect = false -- Enable gamma-correct rendering, when supported by the system (boolean) + + t.audio.mic = false -- Request and use microphone capabilities in Android (boolean) + t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only) t.window.title = "Space Love" -- The window title (string) t.window.icon = nil -- Filepath to an image to use as the window's icon (string) @@ -16,15 +20,20 @@ function love.conf(t) t.window.minheight = 1 -- Minimum window height if the window is resizable (number) t.window.fullscreen = false -- Enable fullscreen (boolean) t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string) - t.window.vsync = true -- Enable vertical sync (boolean) + t.window.vsync = 1 -- Vertical sync mode (number) t.window.msaa = 0 -- The number of samples to use with multi-sampled antialiasing (number) + t.window.depth = nil -- The number of bits per sample in the depth buffer + t.window.stencil = nil -- The number of bits per sample in the stencil buffer t.window.display = 1 -- Index of the monitor to show the window in (number) t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean) + t.window.usedpiscale = true -- Enable automatic DPI scaling when highdpi is set to true as well (boolean) t.window.x = nil -- The x-coordinate of the window's position in the specified display (number) t.window.y = nil -- The y-coordinate of the window's position in the specified display (number) t.modules.audio = true -- Enable the audio module (boolean) + t.modules.data = true -- Enable the data module (boolean) t.modules.event = true -- Enable the event module (boolean) + t.modules.font = true -- Enable the font module (boolean) t.modules.graphics = true -- Enable the graphics module (boolean) t.modules.image = true -- Enable the image module (boolean) t.modules.joystick = false -- Enable the joystick module (boolean) @@ -34,9 +43,9 @@ function love.conf(t) t.modules.physics = false -- Enable the physics module (boolean) t.modules.sound = true -- Enable the sound module (boolean) t.modules.system = true -- Enable the system module (boolean) + t.modules.thread = true -- Enable the thread module (boolean) t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update t.modules.touch = false -- Enable the touch module (boolean) t.modules.video = false -- Enable the video module (boolean) t.modules.window = true -- Enable the window module (boolean) - t.modules.thread = true -- Enable the thread module (boolean) end \ No newline at end of file diff --git a/lib/push.lua b/lib/push.lua index 0e0709a..01f8984 100644 --- a/lib/push.lua +++ b/lib/push.lua @@ -1,232 +1,308 @@ --- push.lua v0.2 +-- push.lua v0.4 --- Copyright (c) 2017 Ulysse Ramage +-- Copyright (c) 2020 Ulysse Ramage -- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +local love11 = love.getVersion() == 11 +local getDPI = love11 and love.window.getDPIScale or love.window.getPixelScale +local windowUpdateMode = love11 and love.window.updateMode or function(width, height, settings) + local _, _, flags = love.window.getMode() + for k, v in pairs(settings) do + flags[k] = v + end + love.window.setMode(width, height, flags) + end + local push = { - - defaults = { - fullscreen = false, - resizable = false, - pixelperfect = false, - highdpi = true, - canvas = true - } - + defaults = { + fullscreen = false, + resizable = false, + pixelperfect = false, + highdpi = true, + canvas = true, + stencil = true + } } setmetatable(push, push) ---TODO: rendering resolution? ---TODO: clean up code - function push:applySettings(settings) - for k, v in pairs(settings) do - self["_" .. k] = v - end + for k, v in pairs(settings) do + self["_" .. k] = v + end end -function push:resetSettings() return self:applySettings(self.defaults) end +function push:resetSettings() + return self:applySettings(self.defaults) +end function push:setupScreen(WWIDTH, WHEIGHT, RWIDTH, RHEIGHT, settings) + settings = settings or {} - settings = settings or {} + self._WWIDTH, self._WHEIGHT = WWIDTH, WHEIGHT + self._RWIDTH, self._RHEIGHT = RWIDTH, RHEIGHT - self._WWIDTH, self._WHEIGHT = WWIDTH, WHEIGHT - self._RWIDTH, self._RHEIGHT = RWIDTH, RHEIGHT + self:applySettings(self.defaults) --set defaults first + self:applySettings(settings) --then fill with custom settings - self:applySettings(self.defaults) --set defaults first - self:applySettings(settings) --then fill with custom settings - - love.window.setMode( self._RWIDTH, self._RHEIGHT, { - fullscreen = self._fullscreen, - resizable = self._resizable, - highdpi = self._highdpi - } ) + windowUpdateMode( + self._RWIDTH, + self._RHEIGHT, + { + fullscreen = self._fullscreen, + resizable = self._resizable, + highdpi = self._highdpi + } + ) - self:initValues() + self:initValues() - if self._canvas then - self:setupCanvas({ "default" }) --setup canvas - end + if self._canvas then + self:setupCanvas({"default"}) --setup canvas + end - self._borderColor = {0, 0, 0} + self._borderColor = {0, 0, 0} - self._drawFunctions = { - ["start"] = self.start, - ["end"] = self.finish - } + self._drawFunctions = { + ["start"] = self.start, + ["end"] = self.finish + } - return self + return self end function push:setupCanvas(canvases) - table.insert(canvases, { name = "_render" }) --final render + table.insert(canvases, {name = "_render", private = true}) --final render - self._canvas = true - self.canvases = {} + self._canvas = true + self.canvases = {} - for i = 1, #canvases do - self.canvases[i] = { - name = canvases[i].name, - shader = canvases[i].shader, - canvas = love.graphics.newCanvas(self._WWIDTH, self._WHEIGHT) - } - end + for i = 1, #canvases do + push:addCanvas(canvases[i]) + end - return self + return self +end +function push:addCanvas(params) + table.insert( + self.canvases, + { + name = params.name, + private = params.private, + shader = params.shader, + canvas = love.graphics.newCanvas(self._WWIDTH, self._WHEIGHT), + stencil = params.stencil or self._stencil + } + ) end function push:setCanvas(name) - if not self._canvas then return true end - return love.graphics.setCanvas( self:getCanvasTable(name).canvas ) + if not self._canvas then + return true + end + local canvasTable = self:getCanvasTable(name) + return love.graphics.setCanvas({canvasTable.canvas, stencil = canvasTable.stencil}) end function push:getCanvasTable(name) - for i = 1, #self.canvases do - if self.canvases[i].name == name then - return self.canvases[i] + for i = 1, #self.canvases do + if self.canvases[i].name == name then + return self.canvases[i] + end end - end end function push:setShader(name, shader) - if not shader then - self:getCanvasTable("_render").shader = name - else - self:getCanvasTable(name).shader = shader - end + if not shader then + self:getCanvasTable("_render").shader = name + else + self:getCanvasTable(name).shader = shader + end end function push:initValues() - self._PSCALE = self._highdpi and love.window.getPixelScale() or 1 - - self._SCALE = { - x = self._RWIDTH/self._WWIDTH * self._PSCALE, - y = self._RHEIGHT/self._WHEIGHT * self._PSCALE - } - - if self._stretched then --if stretched, no need to apply offset - self._OFFSET = {x = 0, y = 0} - else - local scale = math.min(self._SCALE.x, self._SCALE.y) - if self._pixelperfect then scale = math.floor(scale) end - - self._OFFSET = {x = (self._SCALE.x - scale) * (self._WWIDTH/2), y = (self._SCALE.y - scale) * (self._WHEIGHT/2)} - self._SCALE.x, self._SCALE.y = scale, scale --apply same scale to X and Y - end - - self._GWIDTH = self._RWIDTH * self._PSCALE - self._OFFSET.x * 2 - self._GHEIGHT = self._RHEIGHT * self._PSCALE - self._OFFSET.y * 2 -end - ---[[ DEPRECATED ]]-- -function push:apply(operation, shader) - if operation == "start" then - self:start() - elseif operation == "finish" or operation == "end" then - self:finish(shader) - end -end + self._PSCALE = (not love11 and self._highdpi) and getDPI() or 1 -function push:start() - if self._canvas then - love.graphics.push() - love.graphics.setCanvas(self.canvases[1].canvas) - else - love.graphics.translate(self._OFFSET.x, self._OFFSET.y) - love.graphics.setScissor(self._OFFSET.x, self._OFFSET.y, self._WWIDTH*self._SCALE.x, self._WHEIGHT*self._SCALE.y) - love.graphics.push() - love.graphics.scale(self._SCALE.x, self._SCALE.y) - end -end + self._SCALE = { + x = self._RWIDTH / self._WWIDTH * self._PSCALE, + y = self._RHEIGHT / self._WHEIGHT * self._PSCALE + } -function push:finish(shader) - love.graphics.setBackgroundColor(unpack(self._borderColor)) - if self._canvas then - local _render = self:getCanvasTable("_render") + if self._stretched then --if stretched, no need to apply offset + self._OFFSET = {x = 0, y = 0} + else + local scale = math.min(self._SCALE.x, self._SCALE.y) + if self._pixelperfect then + scale = math.floor(scale) + end + + self._OFFSET = { + x = (self._SCALE.x - scale) * (self._WWIDTH / 2), + y = (self._SCALE.y - scale) * (self._WHEIGHT / 2) + } + self._SCALE.x, self._SCALE.y = scale, scale --apply same scale to X and Y + end - love.graphics.pop() + self._GWIDTH = self._RWIDTH * self._PSCALE - self._OFFSET.x * 2 + self._GHEIGHT = self._RHEIGHT * self._PSCALE - self._OFFSET.y * 2 +end - love.graphics.setColor(255, 255, 255) +function push:apply(operation, shader) + self._drawFunctions[operation](self, shader) +end - --draw canvas - love.graphics.setCanvas(_render.canvas) - for i = 1, #self.canvases - 1 do --do not draw _render yet - local _table = self.canvases[i] - love.graphics.setShader(_table.shader) - love.graphics.draw(_table.canvas) +function push:start() + if self._canvas then + love.graphics.push() + love.graphics.setCanvas({self.canvases[1].canvas, stencil = self.canvases[1].stencil}) + else + love.graphics.translate(self._OFFSET.x, self._OFFSET.y) + love.graphics.setScissor( + self._OFFSET.x, + self._OFFSET.y, + self._WWIDTH * self._SCALE.x, + self._WHEIGHT * self._SCALE.y + ) + love.graphics.push() + love.graphics.scale(self._SCALE.x, self._SCALE.y) end - love.graphics.setCanvas() - - --draw render - love.graphics.translate(self._OFFSET.x, self._OFFSET.y) - love.graphics.setShader(shader or self:getCanvasTable("_render").shader) - love.graphics.draw(self:getCanvasTable("_render").canvas, 0, 0, 0, self._SCALE.x, self._SCALE.y) +end - --clear canvas - for i = 1, #self.canvases do - love.graphics.setCanvas( self.canvases[i].canvas ) - love.graphics.clear() +function push:applyShaders(canvas, shaders) + local _shader = love.graphics.getShader() + if #shaders <= 1 then + love.graphics.setShader(shaders[1]) + love.graphics.draw(canvas) + else + local _canvas = love.graphics.getCanvas() + + local _tmp = self:getCanvasTable("_tmp") + if not _tmp then --create temp canvas only if needed + self:addCanvas({name = "_tmp", private = true, shader = nil}) + _tmp = self:getCanvasTable("_tmp") + end + + love.graphics.push() + love.graphics.origin() + local outputCanvas + for i = 1, #shaders do + local inputCanvas = i % 2 == 1 and canvas or _tmp.canvas + outputCanvas = i % 2 == 0 and canvas or _tmp.canvas + love.graphics.setCanvas(outputCanvas) + love.graphics.clear() + love.graphics.setShader(shaders[i]) + love.graphics.draw(inputCanvas) + love.graphics.setCanvas(inputCanvas) + end + love.graphics.pop() + + love.graphics.setCanvas(_canvas) + love.graphics.draw(outputCanvas) end + love.graphics.setShader(_shader) +end - love.graphics.setCanvas() - love.graphics.setShader() - else - love.graphics.pop() - love.graphics.setScissor() - end +function push:finish(shader) + love.graphics.setBackgroundColor(unpack(self._borderColor)) + if self._canvas then + local _render = self:getCanvasTable("_render") + + love.graphics.pop() + + local white = love11 and 1 or 255 + love.graphics.setColor(white, white, white) + + --draw canvas + love.graphics.setCanvas(_render.canvas) + for i = 1, #self.canvases do --do not draw _render yet + local _table = self.canvases[i] + if not _table.private then + local _canvas = _table.canvas + local _shader = _table.shader + self:applyShaders(_canvas, type(_shader) == "table" and _shader or {_shader}) + end + end + love.graphics.setCanvas() + + --draw render + love.graphics.translate(self._OFFSET.x, self._OFFSET.y) + local shader = shader or _render.shader + love.graphics.push() + love.graphics.scale(self._SCALE.x, self._SCALE.y) + self:applyShaders(_render.canvas, type(shader) == "table" and shader or {shader}) + love.graphics.pop() + + --clear canvas + for i = 1, #self.canvases do + love.graphics.setCanvas(self.canvases[i].canvas) + love.graphics.clear() + end + + love.graphics.setCanvas() + love.graphics.setShader() + else + love.graphics.pop() + love.graphics.setScissor() + end end function push:setBorderColor(color, g, b) - self._borderColor = g and {color, g, b} or color + self._borderColor = g and {color, g, b} or color end function push:toGame(x, y) - x, y = x - self._OFFSET.x, y - self._OFFSET.y - local normalX, normalY = x / self._GWIDTH, y / self._GHEIGHT - - x = (x >= 0 and x <= self._WWIDTH * self._SCALE.x) and normalX * self._WWIDTH or nil - y = (y >= 0 and y <= self._WHEIGHT * self._SCALE.y) and normalY * self._WHEIGHT or nil - - return x, y + x, y = x - self._OFFSET.x, y - self._OFFSET.y + local normalX, normalY = x / self._GWIDTH, y / self._GHEIGHT + + x = (x >= 0 and x <= self._WWIDTH * self._SCALE.x) and normalX * self._WWIDTH or nil + y = (y >= 0 and y <= self._WHEIGHT * self._SCALE.y) and normalY * self._WHEIGHT or nil + + return x, y end ---doesn't work - TODO function push:toReal(x, y) - return x+self._OFFSET.x, y+self._OFFSET.y + local realX = self._OFFSET.x + (self._GWIDTH * x) / self._WWIDTH + local realY = self._OFFSET.y + (self._GHEIGHT * y) / self._WHEIGHT + return realX, realY end function push:switchFullscreen(winw, winh) - self._fullscreen = not self._fullscreen - local windowWidth, windowHeight = love.window.getDesktopDimensions() - - if self._fullscreen then --save windowed dimensions for later - self._WINWIDTH, self._WINHEIGHT = self._RWIDTH, self._RHEIGHT - elseif not self._WINWIDTH or not self._WINHEIGHT then - self._WINWIDTH, self._WINHEIGHT = windowWidth * .5, windowHeight * .5 - end - - self._RWIDTH = self._fullscreen and windowWidth or winw or self._WINWIDTH - self._RHEIGHT = self._fullscreen and windowHeight or winh or self._WINHEIGHT - - self:initValues() - - love.window.setFullscreen(self._fullscreen, "desktop") - if not self._fullscreen and (winw or winh) then - love.window.setMode(self._RWIDTH, self._RHEIGHT) --set window dimensions - end + self._fullscreen = not self._fullscreen + local windowWidth, windowHeight = love.window.getDesktopDimensions() + + if self._fullscreen then --save windowed dimensions for later + self._WINWIDTH, self._WINHEIGHT = self._RWIDTH, self._RHEIGHT + elseif not self._WINWIDTH or not self._WINHEIGHT then + self._WINWIDTH, self._WINHEIGHT = windowWidth * .5, windowHeight * .5 + end + + self._RWIDTH = self._fullscreen and windowWidth or winw or self._WINWIDTH + self._RHEIGHT = self._fullscreen and windowHeight or winh or self._WINHEIGHT + + self:initValues() + + love.window.setFullscreen(self._fullscreen, "desktop") + if not self._fullscreen and (winw or winh) then + windowUpdateMode(self._RWIDTH, self._RHEIGHT) --set window dimensions + end end function push:resize(w, h) - local pixelScale = love.window.getPixelScale() - if self._highdpi then w, h = w / pixelScale, h / pixelScale end - self._RWIDTH = w - self._RHEIGHT = h - self:initValues() + if self._highdpi then + w, h = w / self._PSCALE, h / self._PSCALE + end + self._RWIDTH = w + self._RHEIGHT = h + self:initValues() end -function push:getWidth() return self._WWIDTH end -function push:getHeight() return self._WHEIGHT end -function push:getDimensions() return self._WWIDTH, self._WHEIGHT end +function push:getWidth() + return self._WWIDTH +end +function push:getHeight() + return self._WHEIGHT +end +function push:getDimensions() + return self._WWIDTH, self._WHEIGHT +end return push diff --git a/main.lua b/main.lua index 765320a..8f847d0 100644 --- a/main.lua +++ b/main.lua @@ -44,10 +44,10 @@ function love.load() local menuBlinkInterval = 0.6 Timer.every(menuBlinkInterval, function() Timer.tween(menuBlinkInterval / 2, { - [MENU_SELECTED_COLOR] = { r = 100, g = 100, b = 100} + [MENU_SELECTED_COLOR] = { r = 100/255, g = 100/255, b = 100/255} }):finish(function () Timer.tween(menuBlinkInterval / 2, { - [MENU_SELECTED_COLOR] = {r = 150, g = 100, b = 255} + [MENU_SELECTED_COLOR] = {r = 150/255, g = 100/255, b = 255/255} }) end) end) @@ -89,7 +89,7 @@ function love.draw() push:start() gStateStack:render() - love.graphics.setColor(150, 150, 150, 255) + love.graphics.setColor(150/255, 150/255, 150/255, 255/255) love.graphics.setFont(gFonts['default-small']) love.graphics.printf(VERSION, 10, VIRTUAL_HEIGHT-25, VIRTUAL_WIDTH, 'left') diff --git a/sounds/explosion.wav b/sounds/explosion.wav deleted file mode 100644 index c78950555f485e62cda3f6f8477212d705a0ea78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86796 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 diff --git a/src/Dependencies.lua b/src/Dependencies.lua index dfb8935..c3b7eb6 100644 --- a/src/Dependencies.lua +++ b/src/Dependencies.lua @@ -66,38 +66,36 @@ gFonts = { } gSounds = { - ['laser-1'] = love.audio.newSource('sounds/sfx_laser1.ogg'), - ['laser-2'] = love.audio.newSource('sounds/sfx_laser2.ogg'), - ['lose'] = love.audio.newSource('sounds/sfx_lose.ogg'), - ['shield-down'] = love.audio.newSource('sounds/sfx_shieldDown.ogg'), - ['shield-up'] = love.audio.newSource('sounds/sfx_shieldUp.ogg'), - ['two-tone'] = love.audio.newSource('sounds/sfx_twoTone.ogg'), - ['zap'] = love.audio.newSource('sounds/sfx_zap.ogg'), - ['powerup-health'] = love.audio.newSource('sounds/sfx_sounds_powerup12.wav'), - ['health-alarm'] = love.audio.newSource('sounds/sfx_alarm_loop6.wav'), - ['impact'] = love.audio.newSource('sounds/sfx_sounds_impact8.wav'), - ['collision'] = love.audio.newSource('sounds/sfx_sounds_impact11.wav'), - - ['music-title-screen'] = love.audio.newSource('sounds/music/music-title-screen.wav'), - ['music-lvl1'] = love.audio.newSource('sounds/music/music-lvl1.wav'), - ['music-lvl2'] = love.audio.newSource('sounds/music/music-lvl2.wav'), - ['music-lvl3'] = love.audio.newSource('sounds/music/music-lvl3.wav'), - ['music-ending'] = love.audio.newSource('sounds/music/music-ending.wav'), - - ['menu-move'] = love.audio.newSource('sounds/menu/sfx_menu_move1.wav'), - ['menu-select'] = love.audio.newSource('sounds/menu/sfx_menu_select2.wav'), - ['pause-start'] = love.audio.newSource('sounds/menu/sfx_sounds_pause6_in.wav'), - ['pause-end'] = love.audio.newSource('sounds/menu/sfx_sounds_pause6_out.wav'), - - ['explosion'] = love.audio.newSource('sounds/explosion.wav') + ['laser-1'] = love.audio.newSource('sounds/sfx_laser1.ogg', 'static'), + ['laser-2'] = love.audio.newSource('sounds/sfx_laser2.ogg', 'static'), + ['lose'] = love.audio.newSource('sounds/sfx_lose.ogg', 'static'), + ['shield-down'] = love.audio.newSource('sounds/sfx_shieldDown.ogg', 'static'), + ['shield-up'] = love.audio.newSource('sounds/sfx_shieldUp.ogg', 'static'), + ['two-tone'] = love.audio.newSource('sounds/sfx_twoTone.ogg', 'static'), + ['zap'] = love.audio.newSource('sounds/sfx_zap.ogg', 'static'), + ['powerup-health'] = love.audio.newSource('sounds/sfx_sounds_powerup12.wav', 'static'), + ['health-alarm'] = love.audio.newSource('sounds/sfx_alarm_loop6.wav', 'static'), + ['impact'] = love.audio.newSource('sounds/sfx_sounds_impact8.wav', 'static'), + ['collision'] = love.audio.newSource('sounds/sfx_sounds_impact11.wav', 'static'), + + ['music-title-screen'] = love.audio.newSource('sounds/music/music-title-screen.wav', 'stream'), + ['music-lvl1'] = love.audio.newSource('sounds/music/music-lvl1.wav', 'stream'), + ['music-lvl2'] = love.audio.newSource('sounds/music/music-lvl2.wav', 'stream'), + ['music-lvl3'] = love.audio.newSource('sounds/music/music-lvl3.wav', 'stream'), + ['music-ending'] = love.audio.newSource('sounds/music/music-ending.wav', 'stream'), + + ['menu-move'] = love.audio.newSource('sounds/menu/sfx_menu_move1.wav', 'static'), + ['menu-select'] = love.audio.newSource('sounds/menu/sfx_menu_select2.wav', 'static'), + ['pause-start'] = love.audio.newSource('sounds/menu/sfx_sounds_pause6_in.wav', 'static'), + ['pause-end'] = love.audio.newSource('sounds/menu/sfx_sounds_pause6_out.wav', 'static'), } for i = 1, EXPLOSION_SHORT_COUNT, 1 do - gSounds['explosion-short-' .. i] = love.audio.newSource('sounds/explosion_short/sfx_exp_short_hard' .. i ..'.wav') + gSounds['explosion-short-' .. i] = love.audio.newSource('sounds/explosion_short/sfx_exp_short_hard' .. i ..'.wav', 'static') end for i = 1, EXPLOSION_MEDIUM_COUNT, 1 do - gSounds['explosion-medium-' .. i] = love.audio.newSource('sounds/explosion_medium/sfx_exp_medium' .. i ..'.wav') + gSounds['explosion-medium-' .. i] = love.audio.newSource('sounds/explosion_medium/sfx_exp_medium' .. i ..'.wav', 'static') end for k, sound in pairs(gSounds) do @@ -106,7 +104,7 @@ for k, sound in pairs(gSounds) do sound:setLooping(true) end end -gSounds['explosion']:setVolume(0.7) + gSounds['health-alarm']:setLooping(true) diff --git a/src/Utils.lua b/src/Utils.lua index 564a870..f7f101a 100644 --- a/src/Utils.lua +++ b/src/Utils.lua @@ -118,7 +118,7 @@ end function getBlast(size) local blast = love.graphics.newCanvas(size, size) love.graphics.setCanvas(blast) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.circle("fill", size/2, size/2, size/2) love.graphics.setCanvas() return blast @@ -131,7 +131,7 @@ function getExplosion(image) pSystem = love.graphics.newParticleSystem(image, 50) pSystem:setParticleLifetime(0.8, 0.8) pSystem:setLinearAcceleration(-100, -100, 100, 100) - pSystem:setColors(255, 255, 0, 255, 255, 153, 51, 255, 64, 64, 64, 0) + pSystem:setColors(255/255, 255/255, 0, 255/255, 255/255, 153/255, 51/255, 255/255, 64/255, 64/255, 64/255, 0) pSystem:setSizes(0.5, 0.7) return pSystem end @@ -171,7 +171,7 @@ end function writeSaveFile(file, data, mode) - if mode == "append" and love.filesystem.exists(FILE_HIGHSCORES) then + if mode == "append" and love.filesystem.getInfo(FILE_HIGHSCORES) then success, message = love.filesystem.append(FILE_HIGHSCORES, data) fsType = "fs-append" else @@ -190,17 +190,17 @@ end function color2rgb(color) color = color:lower() if color == "red" then - return {r = 255, g = 0, b = 0} + return {r = 1, g = 0, b = 0} elseif color == "green" then - return {r = 0, g = 255, b = 0} + return {r = 0, g = 1, b = 0} elseif color == "blue" then - return {r = 0, g = 0, b = 255} + return {r = 0, g = 0, b = 1} elseif color == "white" then - return {r = 255, g = 255, b = 255} + return {r = 1, g = 1, b = 1} elseif color == "black" then return {r = 0, g = 0, b = 0} elseif color == "orange" then - return {r = 255, g = 140, b = 0} + return {r = 1, g = 140/255, b = 0} end end @@ -224,7 +224,7 @@ function gradient(colors) else x, y = i - 1, 0 end - result:setPixel(x, y, color[1], color[2], color[3], color[4] or 255) + result:setPixel(x, y, color[1], color[2], color[3], color[4] or 1) end result = love.graphics.newImage(result) result:setFilter('linear', 'linear') diff --git a/src/constants.lua b/src/constants.lua index 8779ce1..1dffacc 100644 --- a/src/constants.lua +++ b/src/constants.lua @@ -16,7 +16,7 @@ BACKGROUND_SPEED = 50 BACKGROUNDS = {'bg_black', 'bg_blue', 'bg_dark-purple'} MENU_BACKGROUND = 'bg_black' -MENU_SELECTED_COLOR = {r = 150, g = 100, b = 255} +MENU_SELECTED_COLOR = {r = 150/255, g = 100/255, b = 255/255} PLAYER_LASER_SPEED = 600 * GAME_SPEED_MULTIPLIER diff --git a/src/entity/Entity.lua b/src/entity/Entity.lua index 1b54ce9..d8c28c3 100644 --- a/src/entity/Entity.lua +++ b/src/entity/Entity.lua @@ -98,7 +98,6 @@ function Entity:createHealthbar() parentOffset = offset, width = barWidth, height = 5, - color = {r = 255, g = 255, b = 255}, max = self.health, value = self.health, separators = true diff --git a/src/entity/Player.lua b/src/entity/Player.lua index 1c66021..cd31a4d 100644 --- a/src/entity/Player.lua +++ b/src/entity/Player.lua @@ -177,7 +177,6 @@ function Player:shieldUp(time) y = HUD_PADDING + HUD_ITEM_MARGIN, width = 150, height = 10, - color = {r = 255, g = 255, b = 255}, max = time, value = time, text = "shield" diff --git a/src/entity/Ufo.lua b/src/entity/Ufo.lua index 98f5f8b..6b0d8cf 100644 --- a/src/entity/Ufo.lua +++ b/src/entity/Ufo.lua @@ -28,7 +28,6 @@ function Ufo:createHealthbar() parentOffset = offset, width = barWidth, height = 5, - color = {r = 255, g = 255, b = 255}, max = self.health, value = self.health, separators = true, diff --git a/src/gui/LowHealthOverlay.lua b/src/gui/LowHealthOverlay.lua index 9a669b8..d9fefb8 100644 --- a/src/gui/LowHealthOverlay.lua +++ b/src/gui/LowHealthOverlay.lua @@ -45,7 +45,7 @@ function LowHealthOverlay:render() if self.mode == "full" then love.graphics.setColor(self.color.r, self.color.g, self.color.b, self.alpha) love.graphics.rectangle('fill', 0, 0 , VIRTUAL_WIDTH, VIRTUAL_HEIGHT) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) elseif self.mode == "edge" then loc = { {x = 0, y = 0, w = self.width, h = VIRTUAL_HEIGHT}, diff --git a/src/gui/Menu.lua b/src/gui/Menu.lua index 92242a8..9a9121c 100644 --- a/src/gui/Menu.lua +++ b/src/gui/Menu.lua @@ -79,7 +79,7 @@ function Menu:render() if k == self.selected then love.graphics.setColor(MENU_SELECTED_COLOR.r, MENU_SELECTED_COLOR.g, MENU_SELECTED_COLOR.b, 255) else - love.graphics.setColor(100, 100, 100, 255) + love.graphics.setColor(100/255, 100/255, 100/255, 255/255) end love.graphics.printf(text, self.x, self.y + offsetY, VIRTUAL_WIDTH, 'center') @@ -92,14 +92,14 @@ function Menu:render() -- Then print the option text if k == self.selected then - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) else - love.graphics.setColor(100, 100, 100, 255) + love.graphics.setColor(100/255, 100/255, 100/255, 255/255) end love.graphics.printf(self:getSelectedSideText(k), self.x, self.y + offsetY, VIRTUAL_WIDTH, 'center') end offsetY = offsetY + self.rowOffset end - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) end \ No newline at end of file diff --git a/src/gui/PlayerHealthBar.lua b/src/gui/PlayerHealthBar.lua index d1abe27..d8955d4 100644 --- a/src/gui/PlayerHealthBar.lua +++ b/src/gui/PlayerHealthBar.lua @@ -2,7 +2,7 @@ PlayerHealthBar = Class{__includes = ProgressBar} function PlayerHealthBar:init(def) ProgressBar.init(self, def) - self.color = {r = 0, g = 255, b = 0} + self.color = {r = 0, g = 1, b = 0} self.text = "health" self.separators = true end @@ -13,10 +13,10 @@ function PlayerHealthBar:update(dt) local frac = self.value / self.max if frac > 0.5 then - self.color = {r = 0, g = 255, b = 0} + self.color = {r = 0, g = 1, b = 0} elseif self.value > 1 then - self.color = {r = 255, g = 255, b = 0} + self.color = {r = 1, g = 1, b = 0} else - self.color = {r = 255, g = 0, b = 0} + self.color = {r = 1, g = 0, b = 0} end end \ No newline at end of file diff --git a/src/gui/ProgressBar.lua b/src/gui/ProgressBar.lua index 1d1a709..b43c075 100644 --- a/src/gui/ProgressBar.lua +++ b/src/gui/ProgressBar.lua @@ -18,9 +18,9 @@ function ProgressBar:init(def) self.width = def.width self.height = def.height - self.color = def.color or {r = 255, g = 255, b = 255} -- defaults to white + self.color = def.color or {r = 1, g = 1, b = 1} -- defaults to white self.outlineColor = def.outlineColor or {r = 0, g = 0, b = 0} -- defaults to black - self.textColor = def.textColor or {r = 255, g = 255, b = 255} -- defaults to white + self.textColor = def.textColor or {r = 1, g = 1, b = 1} -- defaults to white self.value = def.value or 0 self.min = def.min or 0 @@ -49,7 +49,7 @@ function ProgressBar:render() -- print text above bar (if set) local yOffset = self.text and HEALTH_BAR_TEXT_OFFSET or 0 if self.text then - love.graphics.setColor(self.textColor.r, self.textColor.g, self.textColor.b, 255) + love.graphics.setColor(self.textColor.r, self.textColor.g, self.textColor.b, 1) love.graphics.setFont(self.font) love.graphics.print(self.text, self.x, self.y) end @@ -61,12 +61,12 @@ function ProgressBar:render() if value > 0 then -- draw main bar, with calculated width based on value / max - love.graphics.setColor(self.color.r, self.color.g, self.color.b, 255) + love.graphics.setColor(self.color.r, self.color.g, self.color.b, 1) love.graphics.rectangle('fill', self.x, self.y + yOffset, renderWidth, self.height, 2) end -- draw outline around actual bar - love.graphics.setColor(self.outlineColor.r, self.outlineColor.g, self.outlineColor.b, 255) + love.graphics.setColor(self.outlineColor.r, self.outlineColor.g, self.outlineColor.b, 1) love.graphics.rectangle('line', self.x, self.y + yOffset, self.width, self.height, 2) if self.separators then @@ -76,5 +76,5 @@ function ProgressBar:render() end end - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) end \ No newline at end of file diff --git a/src/object/GameObject.lua b/src/object/GameObject.lua index 71e92c6..eb88437 100644 --- a/src/object/GameObject.lua +++ b/src/object/GameObject.lua @@ -158,13 +158,13 @@ end function GameObject:render() if self.blinking then if self.blinkTimer > self.blinkInterval / 2 then - love.graphics.setColor(255, 255, 255, 16) + love.graphics.setColor(1, 1, 1, 16/255) end if self.blinkTimer > self.blinkInterval then self.blinkTimer = 0 end else - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) end local frame @@ -180,18 +180,18 @@ function GameObject:render() end end - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) if DEBUG then - love.graphics.setColor(100, 100, 100, 255) + love.graphics.setColor(100/255, 100/255, 100/255, 1) love.graphics.rectangle('line', self.x, self.y, self.width, self.height) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) if self.type == "meteor" then local hitbox = self:getHitbox() - love.graphics.setColor(0, 255, 255, 255) + love.graphics.setColor(0, 1, 1, 1) love.graphics.rectangle('line', hitbox.x, hitbox.y, hitbox.width, hitbox.height) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) end end end \ No newline at end of file diff --git a/src/states/entity/EntityBaseState.lua b/src/states/entity/EntityBaseState.lua index 3b46c04..b1ec1a8 100644 --- a/src/states/entity/EntityBaseState.lua +++ b/src/states/entity/EntityBaseState.lua @@ -13,20 +13,20 @@ function EntityBaseState:exit() end function EntityBaseState:processAI(params, dt) end function EntityBaseState:render() - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(gTextures[self.entity.texture], gFrames[self.entity.texture][self.entity:getFrame()], math.floor(self.entity.x), math.floor(self.entity.y)) if DEBUG then - love.graphics.setColor(255, 0, 255, 255) + love.graphics.setColor(1, 0, 1, 1) love.graphics.rectangle('line', self.entity.x, self.entity.y, self.entity.width, self.entity.height) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) local hitboxes = self.entity:getHitboxes() for k, hitbox in pairs(hitboxes) do - love.graphics.setColor(0, 255, 255, 255) + love.graphics.setColor(0, 1, 1, 1) love.graphics.rectangle('line', hitbox.x, hitbox.y, hitbox.width, hitbox.height) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) end end end diff --git a/src/states/game/GameOverState.lua b/src/states/game/GameOverState.lua index 5086859..b282aa9 100644 --- a/src/states/game/GameOverState.lua +++ b/src/states/game/GameOverState.lua @@ -63,7 +63,7 @@ function GameOverState:render() self.background:render() self.menu:render() - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.setFont(gFonts['large']) love.graphics.printf('Game Over', 0, VIRTUAL_HEIGHT / 2 - 200, VIRTUAL_WIDTH, 'center') diff --git a/src/states/game/HighscoreState.lua b/src/states/game/HighscoreState.lua index fd585a3..70c6653 100644 --- a/src/states/game/HighscoreState.lua +++ b/src/states/game/HighscoreState.lua @@ -38,7 +38,7 @@ function HighscoreState:update(dt) end function HighscoreState:render() - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) self.background:render() love.graphics.setFont(gFonts['large']) love.graphics.printf('Highscores', 0, 200, VIRTUAL_WIDTH, 'center') @@ -54,7 +54,7 @@ function HighscoreState:render() end function HighscoreState:readScores(limit) - if love.filesystem.exists(FILE_HIGHSCORES) then + if love.filesystem.getInfo(FILE_HIGHSCORES) then content, size = love.filesystem.read(FILE_HIGHSCORES) limitedContent = "" local rows = {} diff --git a/src/states/game/PauseState.lua b/src/states/game/PauseState.lua index a9e2ae8..67b24c1 100644 --- a/src/states/game/PauseState.lua +++ b/src/states/game/PauseState.lua @@ -21,10 +21,10 @@ end function PauseState:render() -- black rectangle with lower alpha to let the background (level) appear inactive - love.graphics.setColor(0, 0, 0, 180) + love.graphics.setColor(0, 0, 0, 180/255) love.graphics.rectangle('fill', 0, 0, VIRTUAL_WIDTH, VIRTUAL_HEIGHT) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.setFont(gFonts['large']) love.graphics.printf("Game paused", 0, VIRTUAL_HEIGHT / 2 - 200, VIRTUAL_WIDTH, 'center') end diff --git a/src/states/game/PlayState.lua b/src/states/game/PlayState.lua index ff0995e..71ed59e 100644 --- a/src/states/game/PlayState.lua +++ b/src/states/game/PlayState.lua @@ -14,7 +14,7 @@ function PlayState:init(params) ]] Event.on('stage-changed', function(stage) self.stageLabelText = stage - self.transitionAlpha = 80 + self.transitionAlpha = 80/255 -- first, over a period of 1 second, transition our alpha to 0 Timer.tween(1, { @@ -64,14 +64,14 @@ function PlayState:render() self.level:render() -- render Stage # label and background rect - love.graphics.setColor(95, 205, 228, 200) + love.graphics.setColor(95/255, 205/255, 228/255, 200/255) love.graphics.rectangle('fill', 0, self.stageLabelY - 2, VIRTUAL_WIDTH, 48) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.setFont(gFonts['large']) love.graphics.printf(self.stageLabelText, 0, self.stageLabelY, VIRTUAL_WIDTH, 'center') -- our transition foreground rectangle - love.graphics.setColor(255, 255, 255, self.transitionAlpha) + love.graphics.setColor(1, 1, 1, self.transitionAlpha) love.graphics.rectangle('fill', 0, 0, VIRTUAL_WIDTH, VIRTUAL_HEIGHT) end diff --git a/src/states/game/SelectShipState.lua b/src/states/game/SelectShipState.lua index d7bdbc0..136ed87 100644 --- a/src/states/game/SelectShipState.lua +++ b/src/states/game/SelectShipState.lua @@ -32,7 +32,7 @@ function SelectShipState:init(params) x = VIRTUAL_WIDTH / 2 - SHIP_DEFS[self.playerShip.ship].width / 2, y = VIRTUAL_HEIGHT / 2 + 100 }, - [self] = { blackAlpha = 255 } + [self] = { blackAlpha = 1 } }) :finish(function() gSounds['music-title-screen']:stop() @@ -193,8 +193,7 @@ function SelectShipState:render() laser:render() end - love.graphics.setBackgroundColor(0.5, 0, 1) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.setFont(gFonts['large']) love.graphics.printf('Select Your Ship', 0, VIRTUAL_HEIGHT / 2 - 240, VIRTUAL_WIDTH, 'center') @@ -208,7 +207,7 @@ function SelectShipState:render() love.graphics.setColor(0, 0, 0, self.blackAlpha) love.graphics.rectangle('fill', 0, 0, VIRTUAL_WIDTH, VIRTUAL_HEIGHT) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(gTextures['sheet'], gFrames['sheet'][Player.getFrame(self.playerShip)], self.playerShip.x, self.playerShip.y) end \ No newline at end of file diff --git a/src/states/game/StartState.lua b/src/states/game/StartState.lua index b72c353..10ddb10 100644 --- a/src/states/game/StartState.lua +++ b/src/states/game/StartState.lua @@ -37,8 +37,7 @@ end function StartState:render() self.background:render() - -- love.graphics.setBackgroundColor(0.5,0,1) - love.graphics.setColor(255, 255, 255, 255) + love.graphics.setColor(1, 1, 1, 1) love.graphics.setFont(gFonts['large']) love.graphics.printf('Space Love', 0, VIRTUAL_HEIGHT / 2 - 120, VIRTUAL_WIDTH, 'center') diff --git a/src/world/Level.lua b/src/world/Level.lua index e05a8cf..836864f 100644 --- a/src/world/Level.lua +++ b/src/world/Level.lua @@ -27,9 +27,9 @@ function Level:init(params) self.background = Background() self.lowHealthOverlay = LowHealthOverlay({ - color = {r = 255, g = 0, b = 0}, + color = {r = 1, g = 0, b = 0}, interval = 1, - maxAlpha = 15, + maxAlpha = 15/255, mode = 'full' }) @@ -263,7 +263,7 @@ function Level:render() end -- Draw screen barriers (for enemies and ufo) - love.graphics.setColor(150, 150, 150, 255) + love.graphics.setColor(150/255, 150/255, 150/255, 1) love.graphics.line(0, SCREEN_BARRIER_SIZE, VIRTUAL_WIDTH, SCREEN_BARRIER_SIZE) love.graphics.line(0, VIRTUAL_HEIGHT - SCREEN_BARRIER_SIZE, VIRTUAL_WIDTH, VIRTUAL_HEIGHT - SCREEN_BARRIER_SIZE) end @@ -371,10 +371,14 @@ end function Level:pauseAudio() gSounds['music-lvl' .. self.stage]:pause() - gSounds['health-alarm']:pause() + if self.lowHealthOverlay.enabled then + gSounds['health-alarm']:pause() + end end function Level:resumeAudio() - gSounds['music-lvl' .. self.stage]:resume() - gSounds['health-alarm']:resume() + gSounds['music-lvl' .. self.stage]:play() + if self.lowHealthOverlay.enabled then + gSounds['health-alarm']:play() + end end \ No newline at end of file