Added options menu and menu transitions.
This commit is contained in:
@@ -22,11 +22,12 @@ function GameState:_init(name, index)
|
|||||||
Drawable._init(self)
|
Drawable._init(self)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.index = index
|
self.index = index
|
||||||
|
self.next_state = self.index
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function GameState:update(_)
|
function GameState:update(_)
|
||||||
return self.index
|
return self.next_state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,46 +5,38 @@
|
|||||||
local love = require 'love'
|
local love = require 'love'
|
||||||
local assets = require 'src.utils.asstmngr'
|
local assets = require 'src.utils.asstmngr'
|
||||||
local make_class = require 'src.utils.classes'
|
local make_class = require 'src.utils.classes'
|
||||||
|
local constants = require 'src.gstates.menus.const'
|
||||||
local GameState = require 'src.gstates.gstate'
|
local GameState = require 'src.gstates.gstate'
|
||||||
|
local MainMenu = require 'src.gstates.menus.mainmenu'
|
||||||
|
local OptionsMenu = require 'src.gstates.menus.options'
|
||||||
local Fader = require 'src.graphics.fader'
|
local Fader = require 'src.graphics.fader'
|
||||||
local Sprite = require 'src.graphics.sprite'
|
|
||||||
local Cursor = require 'src.ui.cursor'
|
local Cursor = require 'src.ui.cursor'
|
||||||
local Font = require 'src.ui.font'
|
local Font = require 'src.ui.font'
|
||||||
local SoundEffect = require 'src.sound.sfx'
|
local SoundEffect = require 'src.sound.sfx'
|
||||||
local VBox = require 'src.ui.vbox'
|
|
||||||
local Color = require 'src.utils.color'
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
-- Class definitions
|
-- Class definitions
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
local MainMenu = make_class(GameState)
|
local Menu = make_class(GameState)
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
-- Class methods
|
-- Class methods
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
function MainMenu:_init(name, index)
|
function Menu:_init(name, index)
|
||||||
GameState._init(self, name, index)
|
GameState._init(self, name, index)
|
||||||
self.next_state = self.index
|
|
||||||
self.fade = Fader()
|
self.fade = Fader()
|
||||||
|
self.current_menu = constants.MAIN_MENU
|
||||||
|
self.next_menu = constants.MAIN_MENU
|
||||||
|
self.all_loaded = false
|
||||||
|
|
||||||
-- Create sprites and buttons.
|
-- Create sprites and buttons.
|
||||||
self.background = Sprite('imgs/concb03.png')
|
|
||||||
self.btn_font = Font('fonts/Concrete.ttf')
|
self.btn_font = Font('fonts/Concrete.ttf')
|
||||||
self.title_font = Font('fonts/BBrick.ttf', 35)
|
self.title_font = Font('fonts/BBrick.ttf', 35)
|
||||||
|
|
||||||
-- Create UI elements.
|
|
||||||
self.btns = VBox(15, 5, love.graphics.getWidth())
|
|
||||||
self.btns:add_label('LoveDOS', self.title_font, Color(215, 0, 0), true)
|
|
||||||
self.btns:add_text_button('New Game', self.btn_font)
|
|
||||||
self.btns:add_text_button('Load Game', self.btn_font)
|
|
||||||
self.btns:add_text_button('Options', self.btn_font)
|
|
||||||
self.btns:add_text_button('Help & Story', self.btn_font)
|
|
||||||
self.btns:add_text_button('Quit', self.btn_font, function() self.next_state = -1 end)
|
|
||||||
|
|
||||||
-- Create a mouse cursor object at the current mouse position.
|
-- Create a mouse cursor object at the current mouse position.
|
||||||
local mx, my = love.mouse.getPosition()
|
local mx, my = love.mouse.getPosition()
|
||||||
self.cursor = Cursor(mx, my)
|
self.cursor = Cursor(mx, my)
|
||||||
@@ -52,35 +44,62 @@ function MainMenu:_init(name, index)
|
|||||||
-- Create sound effects.
|
-- Create sound effects.
|
||||||
self.bgm = SoundEffect('bgm/eskisky.wav')
|
self.bgm = SoundEffect('bgm/eskisky.wav')
|
||||||
|
|
||||||
|
-- Create the sub-menus.
|
||||||
|
self.menus = { }
|
||||||
|
self.menus[constants.MAIN_MENU] = MainMenu(self, self.title_font, self.btn_font)
|
||||||
|
self.menus[constants.OPTIONS_MENU] = OptionsMenu(self, self.title_font, self.btn_font)
|
||||||
|
|
||||||
-- Register all assets.
|
-- Register all assets.
|
||||||
assets:register(self.name, self.btn_font)
|
assets:register(self.name, self.btn_font)
|
||||||
assets:register(self.name, self.title_font)
|
assets:register(self.name, self.title_font)
|
||||||
assets:register(self.name, self.background)
|
|
||||||
assets:register(self.name, self.cursor)
|
assets:register(self.name, self.cursor)
|
||||||
assets:register(self.name, self.bgm)
|
assets:register(self.name, self.bgm)
|
||||||
assets:register(self.name, self.btns)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:update(dt)
|
function Menu:update(dt)
|
||||||
if assets:done(self.name) then
|
|
||||||
if not self.bgm:isPlaying() then self.bgm:play() end
|
if not self.bgm:isPlaying() then self.bgm:play() end
|
||||||
|
|
||||||
-- Update the fader.
|
if self.all_loaded then
|
||||||
|
self.menus[self.current_menu]:update(dt)
|
||||||
|
|
||||||
|
-- If the game state changed then trigger a fade out.
|
||||||
|
if self.next_menu ~= self.current_menu and self.fade.done then
|
||||||
|
self.fade:fade_out()
|
||||||
|
end
|
||||||
|
|
||||||
self.fade:update(dt)
|
self.fade:update(dt)
|
||||||
|
|
||||||
|
-- Update the game state.
|
||||||
|
if self.menus[self.next_menu] == nil then
|
||||||
|
error(string.format('%s: switched to unknown menu', self.next_menu))
|
||||||
else
|
else
|
||||||
|
-- If the new state exists then unload it's data and set the new state.
|
||||||
|
if self.next_menu ~= self.current_menu and self.fade.done then
|
||||||
|
self.current_menu = self.next_menu
|
||||||
|
self.fade:fade_in()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local done = true
|
||||||
|
|
||||||
assets:update(self.name)
|
assets:update(self.name)
|
||||||
|
|
||||||
|
for _, v in pairs(self.menus) do
|
||||||
|
assets:update(v.name)
|
||||||
|
done = done and assets:done(v.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.all_loaded = assets:done(self.name) and done
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.next_state
|
return self.next_state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:draw()
|
function Menu:draw()
|
||||||
if assets:done(self.name) then
|
if self.all_loaded then
|
||||||
self.background:draw()
|
self.menus[self.current_menu]:draw()
|
||||||
|
|
||||||
self.btns:draw()
|
|
||||||
self.cursor:draw()
|
self.cursor:draw()
|
||||||
self.fade:draw()
|
self.fade:draw()
|
||||||
else
|
else
|
||||||
@@ -89,23 +108,23 @@ function MainMenu:draw()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:keypressed(_)
|
function Menu:mousemoved(x, y, dx, dy)
|
||||||
end
|
self.menus[self.current_menu]:mousemoved(x, y, dx, dy)
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:mousemoved(x, y, dx, dy)
|
|
||||||
self.btns:mousemoved(x, y, dx, dy)
|
|
||||||
self.cursor:mousemoved(x, y, dx, dy)
|
self.cursor:mousemoved(x, y, dx, dy)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:mousepressed(x, y, btn)
|
function Menu:mousepressed(x, y, btn)
|
||||||
self.btns:mousepressed(x, y, btn)
|
if self.fade.done then
|
||||||
|
self.menus[self.current_menu]:mousepressed(x, y, btn)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MainMenu:mousereleased(x, y, btn)
|
function Menu:mousereleased(x, y, btn)
|
||||||
self.btns:mousereleased(x, y, btn)
|
if self.fade.done then
|
||||||
|
self.menus[self.current_menu]:mousereleased(x, y, btn)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -113,4 +132,4 @@ end
|
|||||||
-- Module return
|
-- Module return
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
return MainMenu
|
return Menu
|
||||||
|
|||||||
75
src/gstates/menus/base.lua
Normal file
75
src/gstates/menus/base.lua
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Imports
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local love = require 'love'
|
||||||
|
local assets = require 'src.utils.asstmngr'
|
||||||
|
local make_class = require 'src.utils.classes'
|
||||||
|
local GameState = require 'src.gstates.gstate'
|
||||||
|
local Sprite = require 'src.graphics.sprite'
|
||||||
|
local VBox = require 'src.ui.vbox'
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Class definitions
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local BaseMenu = make_class(GameState)
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Class methods
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function BaseMenu:_init(parent, name, index, bckg)
|
||||||
|
GameState._init(self, name, index)
|
||||||
|
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
-- Create background sprite and container.
|
||||||
|
self.background = Sprite(bckg)
|
||||||
|
self.container = VBox(15, 5, love.graphics.getWidth())
|
||||||
|
|
||||||
|
-- Register the background and container into the asset manager.
|
||||||
|
assets:register(self.name, self.background)
|
||||||
|
assets:register(self.name, self.container)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function BaseMenu:mousemoved(x, y, dx, dy)
|
||||||
|
self.container:mousemoved(x, y, dx, dy)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function BaseMenu:mousepressed(x, y, btn)
|
||||||
|
self.container:mousepressed(x, y, btn)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function BaseMenu:mousereleased(x, y, btn)
|
||||||
|
self.container:mousereleased(x, y, btn)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function BaseMenu:update()
|
||||||
|
if not assets:done(self.name) then
|
||||||
|
assets:update(self.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function BaseMenu:draw()
|
||||||
|
if assets:done(self.name) then
|
||||||
|
self.background:draw()
|
||||||
|
self.container:draw()
|
||||||
|
else
|
||||||
|
assets:draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Module return
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return BaseMenu
|
||||||
17
src/gstates/menus/const.lua
Normal file
17
src/gstates/menus/const.lua
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Constants
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local constants = {
|
||||||
|
MAIN_MENU = 1,
|
||||||
|
OPTIONS_MENU = 2,
|
||||||
|
STORY = 3,
|
||||||
|
LOAD_MENU = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Module return
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return constants
|
||||||
39
src/gstates/menus/mainmenu.lua
Normal file
39
src/gstates/menus/mainmenu.lua
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Imports
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local make_class = require 'src.utils.classes'
|
||||||
|
local constants = require 'src.gstates.menus.const'
|
||||||
|
local BaseMenu = require 'src.gstates.menus.base'
|
||||||
|
local Color = require 'src.utils.color'
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Class definitions
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local MainMenu = make_class(BaseMenu)
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Main Menu Class methods
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function MainMenu:_init(parent, title_font, button_font)
|
||||||
|
BaseMenu._init(self, parent, "Main Menu", constants.MAIN_MENU, 'imgs/concb03.png')
|
||||||
|
|
||||||
|
-- Create UI elements of the main menu.
|
||||||
|
self.container:add_label('LoveDOS', title_font, Color(215, 0, 0), true)
|
||||||
|
self.container:add_text_button('New Game', button_font)
|
||||||
|
self.container:add_text_button('Load Game', button_font)
|
||||||
|
self.container:add_text_button('Options', button_font, function() parent.next_menu = constants.OPTIONS_MENU end)
|
||||||
|
self.container:add_text_button('Help & Story', button_font)
|
||||||
|
self.container:add_text_button('Quit', button_font, function() parent.next_state = -1 end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Module return
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return MainMenu
|
||||||
39
src/gstates/menus/options.lua
Normal file
39
src/gstates/menus/options.lua
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Imports
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local make_class = require 'src.utils.classes'
|
||||||
|
local constants = require 'src.gstates.menus.const'
|
||||||
|
local BaseMenu = require 'src.gstates.menus.base'
|
||||||
|
local Color = require 'src.utils.color'
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Class definitions
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local OptionsMenu = make_class(BaseMenu)
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Class methods
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function OptionsMenu:_init(parent, title_font, button_font)
|
||||||
|
BaseMenu._init(self, parent, "Options Menu", constants.OPTIONS_MENU, 'imgs/cpu.png')
|
||||||
|
|
||||||
|
-- Create UI elements of the main menu.
|
||||||
|
self.container:add_label('Options', title_font, Color(215, 0, 0), true)
|
||||||
|
self.container:add_label('Enable Permadeath', button_font)
|
||||||
|
self.container:add_label('Controls', button_font)
|
||||||
|
self.container:add_label('Sound Volume', button_font)
|
||||||
|
self.container:add_label('Music Volume', button_font)
|
||||||
|
self.container:add_text_button('Go Back', button_font, function() parent.next_menu = constants.MAIN_MENU end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- Module return
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return OptionsMenu
|
||||||
@@ -26,7 +26,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function SoundEffect:load()
|
function SoundEffect:load()
|
||||||
|
if not self:is_loaded() then
|
||||||
self.sfx = love.audio.newSource(self.file_name)
|
self.sfx = love.audio.newSource(self.file_name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -36,6 +38,11 @@ function SoundEffect:unload()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SoundEffect:is_loaded()
|
||||||
|
return self.sfx ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function SoundEffect:setVolume(volume)
|
function SoundEffect:setVolume(volume)
|
||||||
if self.sfx ~= nil then self.sfx:setVolume(volume) end
|
if self.sfx ~= nil then self.sfx:setVolume(volume) end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
local Intro = require 'src.gstates.intro'
|
local Intro = require 'src.gstates.intro'
|
||||||
local MainMenu = require 'src.gstates.menu'
|
local Menu = require 'src.gstates.menu'
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
@@ -13,7 +13,7 @@ local MainMenu = require 'src.gstates.menu'
|
|||||||
-- Table of all valid game states.
|
-- Table of all valid game states.
|
||||||
local states = {
|
local states = {
|
||||||
Intro('intro', 1),
|
Intro('intro', 1),
|
||||||
MainMenu('menu', 2),
|
Menu('menu', 2),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,14 +65,18 @@ end
|
|||||||
|
|
||||||
function AssetManager:update(owner)
|
function AssetManager:update(owner)
|
||||||
if self.assets[owner] ~= nil then
|
if self.assets[owner] ~= nil then
|
||||||
if self.co == nil then
|
if self.assets[owner].co == nil then
|
||||||
self.co = coroutine.create(_load)
|
self.assets[owner].co = coroutine.create(_load)
|
||||||
end
|
end
|
||||||
|
|
||||||
local errorfree, retval = coroutine.resume(self.co, self, owner)
|
local errorfree, retval = coroutine.resume(self.assets[owner].co, self, owner)
|
||||||
|
|
||||||
if errorfree then
|
if errorfree then
|
||||||
self.assets[owner].done = retval
|
self.assets[owner].done = retval
|
||||||
|
|
||||||
|
if retval then
|
||||||
|
self.assets[owner].co = nil
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error(retval)
|
error(retval)
|
||||||
end
|
end
|
||||||
@@ -96,6 +100,7 @@ function AssetManager:register(owner, asset)
|
|||||||
if self.assets[owner] == nil then
|
if self.assets[owner] == nil then
|
||||||
self.assets[owner] = {
|
self.assets[owner] = {
|
||||||
done = false,
|
done = false,
|
||||||
|
co = nil,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user