From 9523edb555ea96849d766e5a825ab93d22617f1b Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sun, 18 Apr 2021 16:36:40 +0200 Subject: [PATCH] feat: add confirmation dialogs Fixes #86 --- sonic-radiance.love/core/modules/scenes.lua | 2 +- sonic-radiance.love/core/scenemanager.lua | 2 + sonic-radiance.love/game/init.lua | 4 + .../game/modules/confirmdialog/init.lua | 111 ++++++++++++++++++ .../scenes/menus/options/init.lua | 1 + .../scenes/menus/options/widgets.lua | 25 ++++ .../overworld/screens/mainmenu/pause.lua | 17 ++- 7 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 sonic-radiance.love/game/modules/confirmdialog/init.lua diff --git a/sonic-radiance.love/core/modules/scenes.lua b/sonic-radiance.love/core/modules/scenes.lua index fc7c1f4..b01ea17 100644 --- a/sonic-radiance.love/core/modules/scenes.lua +++ b/sonic-radiance.love/core/modules/scenes.lua @@ -92,7 +92,7 @@ end function Scene:updateMenus(dt) if (self.menusystem ~= nil) then self.menusystem:update(dt) - if (core.screen:isActive()) then + if (core.screen:isActive() and (self.dialog == nil)) then self.menusystem:keycheck() end end diff --git a/sonic-radiance.love/core/scenemanager.lua b/sonic-radiance.love/core/scenemanager.lua index c73b75d..cb5e020 100644 --- a/sonic-radiance.love/core/scenemanager.lua +++ b/sonic-radiance.love/core/scenemanager.lua @@ -82,6 +82,7 @@ function SceneManager:update(dt) self.currentScene:setKeys() self.currentScene.assets:update(dt) self.currentScene:updateMenus(dt) + self.currentScene:updateDialog(dt) self.currentScene:updateWorld(dt) self.currentScene:update(dt) self.currentScene:updateEnd(dt) @@ -132,6 +133,7 @@ function SceneManager:draw() self.currentScene:drawWorld() self.currentScene:draw() self.currentScene:drawMenus() + self.currentScene:drawDialog() self.currentScene:drawEnd() self.controller.screen:drawTransition() self.currentScene:drawOverTransition() diff --git a/sonic-radiance.love/game/init.lua b/sonic-radiance.love/game/init.lua index 4bd9292..08dd3af 100644 --- a/sonic-radiance.love/game/init.lua +++ b/sonic-radiance.love/game/init.lua @@ -160,6 +160,10 @@ function Game:removeFromMetadata() self:writeMetadata(metadata) end +function Game:reload() + self:read(self.slot) +end + function Game:read(save_id) self.slot = save_id if (self.slot > 0) then diff --git a/sonic-radiance.love/game/modules/confirmdialog/init.lua b/sonic-radiance.love/game/modules/confirmdialog/init.lua new file mode 100644 index 0000000..e5ff0b7 --- /dev/null +++ b/sonic-radiance.love/game/modules/confirmdialog/init.lua @@ -0,0 +1,111 @@ +local ConfirmDialog = Object:extend() + +local gui = require "game.modules.gui" + +local WIDTH = 256 +local PADWIDTH = 16 +local PADHEIGHT = 16 + +function ConfirmDialog:new(scene, message, choice1func, choice1, choice2func, choice2) + self.scene = scene + self.lines = 2 + self.message = message + + self.choiceLabel = {} + self.choiceFunc = {} + self.choiceSound = {} + self.choiceLabel[1] = choice1 or "Yes" + self.choiceLabel[2] = choice2 or "No" + self.choiceFunc[1] = choice1func + self.choiceFunc[2] = choice2func or function() self:dismiss() end + self.choiceSound[1] = "mSelect" + self.choiceSound[2] = "mBack" + + self.darken = true + + self.currentChoice = 0 + self.cancelChoice = -1 + self.isActive = false + + self.scene.dialog = self + self.texture = self:createTexture() +end + +function ConfirmDialog:setLines(lines) + self.lines = lines + self.texture = self:createTexture() +end + +function ConfirmDialog:createTexture() + self.height = 32 + (self.lines * 16) + PADHEIGHT + return gui.newTextBox("assets/gui/dialogbox.png", WIDTH + PADWIDTH, self.height) +end + +function ConfirmDialog:setCancelChoice(choice) + self.cancelChoice = choice - 1 +end + +function ConfirmDialog:update(dt) + if (self.isActive) then + self:keycheck() + else + self.isActive = true + end +end + +function ConfirmDialog:keycheck() + local keys = self.scene.sources[1].keys + if (keys["up"].isPressed or + self.scene.sources[1].keys["down"].isPressed) then + self.currentChoice = (self.currentChoice + 1) % 2 + self.scene.assets.sfx["mBeep"]:play() + end + + if (keys["A"].isPressed) then + self:doAction(self.currentChoice) + end + + if (keys["B"].isPressed) then + self:doAction(self.cancelChoice) + end + +end + +function ConfirmDialog:doAction(choice) + if (self.choiceFunc[choice + 1] ~= nil) then + self.scene.assets.sfx[self.choiceSound[choice + 1]]:play() + self.choiceFunc[choice + 1]() + end +end + +function ConfirmDialog:dismiss() + self:destroy() +end + +function ConfirmDialog:destroy() + self.scene.dialog = nil +end + +function ConfirmDialog:draw() + local x, y = self:getCoord() + local padx, pady = 8, 6 + if (self.darken) then + love.graphics.setColor(0,0,0,0.5) + love.graphics.rectangle("fill", 0, 0, 424, 240) + utils.graphics.resetColor() + end + love.graphics.draw(self.texture, x, y) + self.scene.assets.fonts["small"]:draw(self.message ,x + padx, y + pady,WIDTH,"left") + for i = 1, 2, 1 do + self.scene.assets.fonts["small"]:draw(self.choiceLabel[i], x + padx + 8, y + pady + (self.lines + i - 1)*16) + if ((self.currentChoice + 1) == i) then + self.scene.assets.fonts["small"]:draw(">", x + padx, y + pady + (self.lines + i - 1)*16) + end + end +end + +function ConfirmDialog:getCoord() + return (424-(WIDTH + PADWIDTH))/2, (240 - self.height)/2 +end + +return ConfirmDialog \ No newline at end of file diff --git a/sonic-radiance.love/scenes/menus/options/init.lua b/sonic-radiance.love/scenes/menus/options/init.lua index a92215d..197e50c 100644 --- a/sonic-radiance.love/scenes/menus/options/init.lua +++ b/sonic-radiance.love/scenes/menus/options/init.lua @@ -29,6 +29,7 @@ function OptionsMenu:new() Widgets.Audio(self, "audio", "sfx", "SFX") Widgets.Audio(self, "audio", "music", "Music") + Widgets.Delete(self, "main") Widgets.Exit(self, "main") self.menusystem.menus["main"]:finalize() diff --git a/sonic-radiance.love/scenes/menus/options/widgets.lua b/sonic-radiance.love/scenes/menus/options/widgets.lua index 76c3eba..283c931 100644 --- a/sonic-radiance.love/scenes/menus/options/widgets.lua +++ b/sonic-radiance.love/scenes/menus/options/widgets.lua @@ -14,8 +14,10 @@ widgets.Lang = RadianceListMenu.DualTextWidget:extend() widgets.PlayerSubMenu = RadianceListMenu.DualTextWidget:extend() widgets.Key = RadianceListMenu.DualTextWidget:extend() widgets.Audio = RadianceListMenu.DualTextWidget:extend() +widgets.Delete = RadianceListMenu.DualTextWidget:extend() local defTransitions = require "core.modules.transitions" +local ConfirmDialog = require "game.modules.confirmdialog" -- BASIC WIDGETS -- Simple and reusables widgets @@ -63,6 +65,29 @@ function widgets.Dummy:action() -- shoosh end +-- Delete Save : delete the current Save + +function widgets.Delete:new(scene, menu) + widgets.Exit.super.new(self, scene, menu, "Delete save", "") + self.color = {1, 0.3, 0.3} +end + +function widgets.Delete:action() + self.scene.assets:playSFX("mSelect") + + local confirm = ConfirmDialog(self.scene, "Do you want to delete your save ? \nYou won't be able to recover your data.", + function() self:deleteSave() end) + confirm:setCancelChoice(2) +end + +function widgets.Delete:deleteSave() + core.scenemanager:setStoredScene("mainmenu") + game:deleteCurrentSave() + core.screen:startTransition(defTransitions.default, defTransitions.circle, + function() scenes.title(true) end, + 424/2, 240/2) +end + -- Exit Widget : exit the examples function widgets.Exit:new(scene, menu) diff --git a/sonic-radiance.love/scenes/overworld/screens/mainmenu/pause.lua b/sonic-radiance.love/scenes/overworld/screens/mainmenu/pause.lua index aa13fae..adf9a53 100644 --- a/sonic-radiance.love/scenes/overworld/screens/mainmenu/pause.lua +++ b/sonic-radiance.love/scenes/overworld/screens/mainmenu/pause.lua @@ -14,6 +14,7 @@ local SaveExitWidget = menu.BaseWidget:extend() local defTransitions = require "core.modules.transitions" local radTransitions = require "game.modules.transitions" +local ConfirmDialog = require "game.modules.confirmdialog" local const = require "scenes.overworld.screens.mainmenu.const" @@ -115,12 +116,22 @@ function SaveExitWidget:action() game:write() end if (self.exit) then - core.screen:startTransition(defTransitions.default, defTransitions.circle, function() scenes.debug.menu() end, 424/2, 240/2) - self.scene.tweens:newTween(0, 0.3, {ringBorder=-16}, "inOutQuad") - self.scene.tweens:newTween(0, 0.3, {timeBorder=-20}, "inOutQuad") + if (self.save) then + self:exitToMenu() + else + local confirm = ConfirmDialog(self.scene, "Do you to exit the game ? \nAll unsaved data will be lost.", + function() self:exitToMenu() end) + confirm:setCancelChoice(2) + end else self.scene:unpause() end end +function SaveExitWidget:exitToMenu() + core.screen:startTransition(defTransitions.default, defTransitions.circle, function() game:reload() scenes.debug.menu() end, 424/2, 240/2) + self.scene.tweens:newTween(0, 0.3, {ringBorder=-16}, "inOutQuad") + self.scene.tweens:newTween(0, 0.3, {timeBorder=-20}, "inOutQuad") +end + return PauseScreen