From 0343c017d39137fc8b975e46449b8981708e6141 Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Thu, 16 Sep 2021 20:59:57 +0200 Subject: [PATCH] improvement: port the option menu to gui --- .../scenes/menus/options/init.lua | 106 +------ .../scenes/menus/options/menu.lua | 223 ++++++++++++- .../scenes/menus/options/widgets.lua | 300 ------------------ 3 files changed, 220 insertions(+), 409 deletions(-) delete mode 100644 sonic-radiance.love/scenes/menus/options/widgets.lua diff --git a/sonic-radiance.love/scenes/menus/options/init.lua b/sonic-radiance.love/scenes/menus/options/init.lua index a0e5f7b..7e4e7b4 100644 --- a/sonic-radiance.love/scenes/menus/options/init.lua +++ b/sonic-radiance.love/scenes/menus/options/init.lua @@ -2,123 +2,33 @@ local Scene = require "game.scenes" local OptionsMenu = Scene:extend() local OptionMenu = require "scenes.menus.options.menu" -local Widgets = require "scenes.menus.options.widgets" local gui = require "game.modules.gui" local MenuBack = require "game.modules.gui.menuback" function OptionsMenu:new() - OptionsMenu.super.new(self) - - self:addMenu("main", true) - self:addSubMenu("video", "Video") - self:addSubMenu("audio", "Audio") - --self:addSubMenu("langs", "langs") - self:addSubMenu("inputs", "Inputs") - self:addSubMenu("difficulty", "Difficulty") - - Widgets.Resolution(self, "video") - Widgets.Switch(self, "video", "fullscreen", "Fullscreen") - Widgets.Switch(self, "video", "borders", "Borders") - Widgets.Switch(self, "video", "vsync", "Vsync") - - self:addPlayerMenus() - self:addDifficultyMenu() - - --self:setLanguageMenu() - - 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() - self.menusystem:switchMenu("main") - - self.menusystem:setSoundFromSceneAssets("mBeep") + OptionsMenu.super.new(self, true, true) self.keyDetector = {} self.keyDetector.widget = nil - self.borderY = 30 - self.borders = gui.newBorder(424, 30, 8) - - self.back = MenuBack() -end - -function OptionsMenu:update(dt) - self.back:update(dt) -end - --- MENU FUNCTION --- Functions that serve the handling of menus - -function OptionsMenu:addMenu(name, nobackbutton) - OptionMenu(self, name) -end - -function OptionsMenu:addSubMenu(name, fullname) - self.menusystem.menus["main"]:addSubMenu(name, fullname) -end - -function OptionsMenu:addDifficultyMenu() - Widgets.DiffSwitch(self, "difficulty", "hazardMakesKo", "Hazards can make KO") - Widgets.DiffSwitch(self, "difficulty", "playerKoChar", "Play KO characters on maps") - Widgets.DiffSwitch(self, "difficulty", "easierBattles", "Easier battles") - Widgets.DiffSwitch(self, "difficulty", "checkPointRegen", "Checkpoints heal you") - Widgets.DiffSwitch(self, "difficulty", "levelUpHeal", "Gaining a level heal") - Widgets.DiffSwitch(self, "difficulty", "allDamage", "Hazards damage everybody") -end - -function OptionsMenu:addPlayerMenus() - for i,v in ipairs(core.input.data) do - - self.menusystem.menus["inputs"]:addSubMenu("player" .. i, "Player " .. i, "inputs") - - local keyList = require "datas.keys" - for j, key in ipairs(keyList) do - Widgets.Key(self, i, key) - end - end - -end - -function OptionsMenu:addScene(submenu, scene, fullname) - Widgets.Dummy(self, submenu, fullname) -end - -function OptionsMenu:setLanguageMenu() - for i,v in ipairs(core.lang.data.available) do - Widgets.Lang(self, "langs", v) - end + OptionMenu() + MenuBack() end function OptionsMenu:changeKey(widget) - self.keyDetector.isActive = true self.keyDetector.widget = widget end function OptionsMenu:keypressed( key ) - if (self.keyDetector.isActive) then + if (self.keyDetector.widget ~= nil) then + self.assets:playSFX("mSelect") + self.gui.elements["optionMenu"].isVisible = true + self.gui:delayFocus("optionMenu", 0.1) self.keyDetector.widget:receiveKey( key ) - self.menusystem:activate() self.keyDetector.isActive = false + self.keyDetector.widget = nil end end -function OptionsMenu:draw() - love.graphics.setColor(1, 1, 1, 1) - love.graphics.rectangle("fill", 0, 0, 424, 240) - self.back:draw() - utils.graphics.resetColor() - self.assets.images["background"]:draw(0, 0) -end - -function OptionsMenu:drawOverTransition() - love.graphics.draw(self.borders, 0, self.borderY, 0, 1, -1) - love.graphics.draw(self.borders, 424, 240 - self.borderY, 0, -1, 1) - self.assets.fonts["small"]:draw("v" .. game.version, 424 - 44, 240 + 10 - self.borderY) -end - return OptionsMenu diff --git a/sonic-radiance.love/scenes/menus/options/menu.lua b/sonic-radiance.love/scenes/menus/options/menu.lua index 1ec8937..52614d1 100644 --- a/sonic-radiance.love/scenes/menus/options/menu.lua +++ b/sonic-radiance.love/scenes/menus/options/menu.lua @@ -1,15 +1,216 @@ -local RadianceListMenu = require "game.modules.menus.list" +local Parent = require "game.modules.gui.boxedmenu" +local MainMenu = Parent:extend() -local OptionMenu = RadianceListMenu.ListMenu:extend() -local WIDTH = 128+108 -local ITEMNUMBER = 6 +local TextMenuWidget = require "birb.modules.gui.textmenu.widgets.basic" +local ResolutionWidget = TextMenuWidget:extend() +local SwitchWidget = TextMenuWidget:extend() +local AudioWidget = TextMenuWidget:extend() +local DifficultyWidget = TextMenuWidget:extend() +local KeysWidget = TextMenuWidget:extend() -function OptionMenu:new(scene, name) - local w, h = math.floor(WIDTH), math.floor(16 * ITEMNUMBER) - local screenw, screenh = core.screen:getDimensions() - local x = (screenw/2) - (w/2) - local y = (screenh/2) - (h/2) - OptionMenu.super.new(self, scene, name, x, y, w, ITEMNUMBER, true) +local defTransitions = require "birb.modules.transitions" +local ConfirmDialog = require "game.modules.confirmdialog" + +local MENU_Y = 48 +local MENU_W = 424 / 1.5 +local MENU_ITEM_NUMBER = 8 + +function MainMenu:new() + local screenw, screenh = core.screen:getDimensions() + MainMenu.super.new(self, "optionMenu", screenw/2, MENU_Y, MENU_W, MENU_ITEM_NUMBER, true) + self.ox = MENU_W/2 + self:addVideoMenu() + self:addAudioMenu() + self:addDifficultyMenu() + self:addInputMenu() + self:switch("main") + self:addItem("Delete save", "left", function() self:deleteSave() end, "select", nil, {1, 0.3, 0.3}) + self:addItem("Exit", "left", function() self:exit() end, "back") + self:setCancelWidget() + self:getFocus() end -return OptionMenu +function MainMenu:addVideoMenu() + self:addSubmenu("video", "Videos", "main", true) + ResolutionWidget() + SwitchWidget("fullscreen", "Fullscreen") + SwitchWidget("border", "Borders") + SwitchWidget("vsync", "Vsync") +end + +function MainMenu:addAudioMenu() + self:addSubmenu("audio", "Audio", "main", true) + AudioWidget("music", "Music") + AudioWidget("sfx", "SFX") +end + +function MainMenu:addDifficultyMenu() + self:addSubmenu("difficulty", "Difficulty", "main", true) + DifficultyWidget("hazardMakesKo", "Hazards can make KO") + DifficultyWidget("playerKoChar", "Play KO characters on maps") + DifficultyWidget("easierBattles", "Easier battles") + DifficultyWidget("checkPointRegen", "Checkpoints heal you") + DifficultyWidget("levelUpHeal", "Gaining a level heal") + DifficultyWidget("allDamage", "Hazards damage everybody") +end + +function MainMenu:addInputMenu() + self:addSubmenu("input", "Input", "main", true) + local keyList = require "datas.keys" + for j, key in ipairs(keyList) do + KeysWidget(key) + end +end + +function MainMenu:exit() + core.screen:startTransition(defTransitions.default, defTransitions.default, + function() scenes.menus.main() end, 0, 0) +end + +function MainMenu:deleteSave() + local confirm = ConfirmDialog(core.scenemanager.currentScene, + "Do you want to delete your save ? \nYou won't be able to recover your data.", + function() + core.scenemanager:setStoredScene("mainmenu") + game:deleteCurrentSave() + core.screen:startTransition(defTransitions.default, defTransitions.circle, + function() scenes.menus.title(true) end, + 424/2, 240/2) + end) + confirm:setCancelChoice(2) +end + + +-- WIDGETS + +function ResolutionWidget:new() + ResolutionWidget.super.new(self, "optionMenu", core.lang:translate("options", "resolution"), "left") + self:addLabel(self:getSecondLabel(), "right") +end + +function ResolutionWidget:getSecondLabel() + return "x" .. core.options.data.video.resolution +end + +function ResolutionWidget:action() + core.options.data.video.resolution = ((core.options.data.video.resolution) % 3) + 1 + self:replaceLabel(2, self:getSecondLabel()) + core.screen:applySettings() + self:invalidateCanvas() + core.options:write() +end + +-- SWITCH + +function SwitchWidget:new(keyname, label) + self.keyname = keyname + SwitchWidget.super.new(self, "optionMenu", label, "left") + self:addLabel(self:getSecondLabel(), "right") +end + +function SwitchWidget:modifyKey() + core.options.data.video[self.keyname] = (core.options.data.video[self.keyname] == false) + core.screen:applySettings() +end + +function SwitchWidget:getKey() + return core.options.data.video[self.keyname] +end + +function SwitchWidget:getSecondLabel() + return core.lang:translate("commons", utils.math.either(self:getKey(), "true", "false")) +end + +function SwitchWidget:action() + self:modifyKey() + self:replaceLabel(2, self:getSecondLabel()) + core.options:write() + self:invalidateCanvas() +end + +-- AUDIO + +function AudioWidget:new(audiotype, label) + self.audiotype = audiotype + SwitchWidget.super.new(self, "optionMenu", label, "left") + self:addLabel(self:getSecondLabel(), "right") + self.order = 0 +end + +function AudioWidget:getSecondLabel() + return utils.math.numberToString(self:getVolume(), 3) .. "%" +end + +function AudioWidget:getVolume() + return core.options.data.audio[self.audiotype] +end + +function AudioWidget:setVolume(vol) + core.options.data.audio[self.audiotype] = utils.math.either(vol >= 0, vol, 100) +end + +function AudioWidget:action() + local value = self:getVolume() + self:setVolume(value - 20) + self:replaceLabel(2, self:getSecondLabel()) + self:invalidateCanvas() + --self.scene.assets.music:setVolume(core.options.data.audio.music / 100) + core.options:write() +end + +-- DIFFICULTY + +function DifficultyWidget:new(keyname, label) + self.keyname = keyname + SwitchWidget.super.new(self, "optionMenu", label, "left") + self:addLabel(self:getSecondLabel(), "right") +end + +function DifficultyWidget:modifyKey() + game.difficulty:toggle(self.keyname) +end + +function DifficultyWidget:getKey() + return game.difficulty:get(self.keyname) +end + +function DifficultyWidget:getSecondLabel() + return core.lang:translate("commons", utils.math.either(self:getKey(), "true", "false")) +end + +function DifficultyWidget:action() + self:modifyKey() + self:replaceLabel(2, self:getSecondLabel()) + game:write() + self:invalidateCanvas() +end + +-- KEYS + +function KeysWidget:new(key) + self.source = 1 + self.key = key + + SwitchWidget.super.new(self, "optionMenu", self.key, "left") + self:addLabel(self:getSecondLabel(), "right") + self.type = "navigate" +end + +function KeysWidget:getSecondLabel() + return core.input.data[self.source].keys[self.key] +end + +function KeysWidget:action() + self.menu:playSFX("navigate") + self.scene:changeKey(self) + self.menu.isVisible = false + self.menu:looseFocus() +end + +function KeysWidget:receiveKey( key ) + core.options:setInputKey(self.source, self.key, key) + self:replaceLabel(2, self:getSecondLabel()) + self:invalidateCanvas() +end + +return MainMenu diff --git a/sonic-radiance.love/scenes/menus/options/widgets.lua b/sonic-radiance.love/scenes/menus/options/widgets.lua deleted file mode 100644 index 9f7e763..0000000 --- a/sonic-radiance.love/scenes/menus/options/widgets.lua +++ /dev/null @@ -1,300 +0,0 @@ -local widgets = {} - -local Widget = require "birb.modules.menusystem.widgets" -local RadianceListMenu = require "game.modules.menus.list" - -local DoubleTextWidget = Widget.Text:extend() - -widgets.SubMenu = DoubleTextWidget:extend() -widgets.Dummy = RadianceListMenu.DualTextWidget:extend() -widgets.Exit = RadianceListMenu.DualTextWidget:extend() -widgets.Switch = RadianceListMenu.DualTextWidget:extend() -widgets.Resolution = RadianceListMenu.DualTextWidget:extend() -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() -widgets.DiffSwitch = RadianceListMenu.DualTextWidget:extend() - -local defTransitions = require "birb.modules.transitions" -local ConfirmDialog = require "game.modules.confirmdialog" - --- BASIC WIDGETS --- Simple and reusables widgets - --- DoubleText widget : a two-side text widget - -function DoubleTextWidget:new(menu, font, label1, label2) - DoubleTextWidget.super.new(self, menu, font, label1) - self.label2 = label2 or "" -end - -function DoubleTextWidget:drawCanvas() - local w, h - w = math.floor(self.width) - h = math.floor(self.height / 2) - (self.font:getHeight() / 2) - self.font:draw(self.label, 4, h, -1, "left") - self.font:draw(self.label2, w-4, h, -1, "right") -end - --- Submenu widget :: go to a submenu - -function widgets.SubMenu:new(scene, menu, newmenu, fullname, order, label2) - self.scene = scene - local widgetmenu = self.scene.menusystem.menus[menu] - local font = self.scene.assets.fonts["medium"] - local label = core.lang:translate("options", fullname) - local label2 = label2 or ">" - self.newmenu = newmenu - widgets.SubMenu.super.new(self, widgetmenu, font, label, label2) - self.order = order or 0 -end - -function widgets.SubMenu:action() - self.scene.assets:playSFX("mSelect") - self.scene.menusystem:switchMenu(self.newmenu) -end - --- Dummy widget :: An empty widget to serve as a base for others - -function widgets.Dummy:new(scene, menu, fullname) - widgets.Dummy.super.new(self, scene, menu, fullname) -end - -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.menus.title(true) end, - 424/2, 240/2) -end - --- Exit Widget : exit the examples - -function widgets.Exit:new(scene, menu) - widgets.Exit.super.new(self, scene, menu, "Exit", "") -end - -function widgets.Exit:action() - self.scene.assets:playSFX("mSelect") - core.scenemanager:setStoredScene("mainmenu") - core.screen:startTransition(defTransitions.default, defTransitions.default, - function() scenes.menus.main() end, - 0, 0) -end - --- VIDEO WIDGETS --- Handle graphical settings - --- Switch widget (One widget to handle graphical switch) - -function widgets.Switch:new(scene, menu, keyname, label) - self.keyname = keyname - local label2 = self:getLabel() - widgets.Switch.super.new(self, scene, menu, label, label2) - self.order = 0 -end - -function widgets.Switch:modifyKey() - --self.key = (self.key == false) - if self.keyname == "fullscreen" then - core.options.data.video.fullscreen = (core.options.data.video.fullscreen == false) - elseif self.keyname == "borders" then - core.options.data.video.border = (core.options.data.video.border == false) - elseif self.keyname == "vsync" then - core.options.data.video.vsync = (core.options.data.video.vsync == false) - end - core.screen:applySettings() -end - -function widgets.Switch:getKey() - if self.keyname == "fullscreen" then - self.key = core.options.data.video.fullscreen - elseif self.keyname == "borders" then - self.key = (core.options.data.video.border) - elseif self.keyname == "vsync" then - self.key = (core.options.data.video.vsync) - end -end - -function widgets.Switch:getLabel() - self:getKey() - local label = "" - if (self.key) then - label = "true" - else - label = "false" - end - - return core.lang:translate("commons", label) -end - -function widgets.Switch:action() - self:modifyKey() - self.scene.assets:playSFX("mSelect") - self.label2 = self:getLabel() - core.options:write() - self:invalidateCanvas() -end - --- Resolution Widget - -function widgets.Resolution:new(scene, menu) - local label = core.lang:translate("options", "resolution") - local label2 = self:getLabel() - widgets.Resolution.super.new(self, scene, menu, label, label2) -end - -function widgets.Resolution:getLabel() - return "x" .. core.options.data.video.resolution -end - -function widgets.Resolution:action() - if core.options.data.video.resolution == 3 then - core.options.data.video.resolution = 1 - else - core.options.data.video.resolution = core.options.data.video.resolution + 1 - end - self.label2 = self:getLabel() - core.screen:applySettings() - self.scene.assets:playSFX("mSelect") - self:invalidateCanvas() - core.options:write() -end - --- Key widgets -function widgets.Key:new(scene, sourceid, key) - self.source = sourceid - self.key = key - - local menu = "player" .. self.source - local label = self.key - local label2 = self:getLabel() - - widgets.Key.super.new(self, scene, menu, label, label2) - self.order = 0 -end - -function widgets.Key:getLabel() - return core.input.data[self.source].keys[self.key] -end - -function widgets.Key:action() - self.scene.assets:playSFX("navigate") - self.scene:changeKey(self) - self.scene.menusystem:deactivate() -end - -function widgets.Key:receiveKey( key ) - self.scene.assets:playSFX("mSelect") - core.options:setInputKey(self.source, self.key, key) - self.label2 = self:getLabel() - self:invalidateCanvas() -end - --- AUDIO FUNCTIONS --- Sounds/Music functions - -function widgets.Audio:new(scene, menu, audiotype, label) - self.audiotype = audiotype - - local label2 = self:getLabel() - widgets.Audio.super.new(self, scene, menu, label, label2) - self.order = 0 -end - -function widgets.Audio:getLabel() - local value = self:getVolume() - string = utils.math.numberToString(value, 3) - local label = string .. "%" - - return label -end - -function widgets.Audio:getVolume() - if (self.audiotype == "sfx") then - return core.options.data.audio.sfx - else - return core.options.data.audio.music - end -end - -function widgets.Audio:setVolume(vol) - if (vol < 0) then vol = 100 end - - if (self.audiotype == "sfx") then - core.options.data.audio.sfx = vol - else - core.options.data.audio.music = vol - end - - self.label2 = self:getLabel() - self:invalidateCanvas() -end - -function widgets.Audio:action() - local value = self:getVolume() - self:setVolume(value - 20) - self.scene.assets:playSFX("mSelect") - --self.scene.assets.music:setVolume(core.options.data.audio.music / 100) - core.options:write() -end - --- Switch widget (One widget to handle graphical switch) - -function widgets.DiffSwitch:new(scene, menu, keyname, label) - self.keyname = keyname - local label2 = self:getLabel() - widgets.Switch.super.new(self, scene, menu, label, label2) - self.order = 0 -end - -function widgets.DiffSwitch:modifyKey() - game.difficulty:toggle(self.keyname) -end - -function widgets.DiffSwitch:getKey() - return game.difficulty:get(self.keyname) -end - -function widgets.DiffSwitch:getLabel() - self.key = self:getKey() - local label = "" - if (self.key) then - label = "true" - else - label = "false" - end - - return core.lang:translate("commons", label) -end - -function widgets.DiffSwitch:action() - self:modifyKey() - self.scene.assets:playSFX("mSelect") - self.label2 = self:getLabel() - game:write() - self:invalidateCanvas() -end - -return widgets