Compare commits
2 Commits
4ad280a820
...
777b70d1ab
| Author | SHA1 | Date | |
|---|---|---|---|
| 777b70d1ab | |||
| 4ecaaf1b50 |
BIN
assets/imgs/tchcmp1.png
Normal file
BIN
assets/imgs/tchcmp1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
15
main.lua
15
main.lua
@@ -2,10 +2,10 @@
|
||||
-- Imports
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local love = require 'love'
|
||||
local game_states = require 'src.states'
|
||||
local settings = require 'src.utils.settings'
|
||||
local Fader = require 'src.graphics.fader'
|
||||
local love = require 'love'
|
||||
local game_states = require 'src.states'
|
||||
local settings = require 'src.utils.settings'
|
||||
local Fader = require 'src.graphics.fader'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@@ -87,13 +87,14 @@ function love.draw()
|
||||
Fade:draw()
|
||||
|
||||
if Debug then
|
||||
love.graphics.setColor(0, 0, 0)
|
||||
love.graphics.rectangle('fill', 0, 0, 140, 50)
|
||||
love.graphics.setColor()
|
||||
-- love.graphics.setColor(0, 0, 0)
|
||||
-- love.graphics.rectangle('fill', 0, 0, 140, 50)
|
||||
love.graphics.setColor(255, 250, 0)
|
||||
love.graphics.print(string.format('OS: %s', love.system.getOS()), 5, 5)
|
||||
love.graphics.print(string.format('Love version: %s', love.getVersion()), 5, 15)
|
||||
love.graphics.print(string.format('Memory usage: %s KiB', love.system.getMemUsage()), 5, 25)
|
||||
love.graphics.print(string.format('FPS: %.2f', 1.0 / love.timer.getAverageDelta()), 5, 35)
|
||||
love.graphics.setColor()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ local make_class = require 'src.utils.classes'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Drawable
|
||||
local Drawable = make_class()
|
||||
|
||||
|
||||
|
||||
@@ -2,18 +2,19 @@
|
||||
-- Imports
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local love = require 'love'
|
||||
local assets = require 'src.utils.asstmngr'
|
||||
local sound_manager = require 'src.sound.sndmngr'
|
||||
local make_class = require 'src.utils.classes'
|
||||
local constants = require 'src.gstates.menus.const'
|
||||
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 Cursor = require 'src.ui.cursor'
|
||||
local Font = require 'src.ui.font'
|
||||
local SoundEffect = require 'src.sound.sfx'
|
||||
local love = require 'love'
|
||||
local assets = require 'src.utils.asstmngr'
|
||||
local sound_manager = require 'src.sound.sndmngr'
|
||||
local dialog_manager = require 'src.ui.dlgmngr'
|
||||
local make_class = require 'src.utils.classes'
|
||||
local constants = require 'src.gstates.menus.const'
|
||||
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 Cursor = require 'src.ui.cursor'
|
||||
local Font = require 'src.ui.font'
|
||||
local SoundEffect = require 'src.sound.sfx'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@@ -63,6 +64,7 @@ function Menu:update(dt)
|
||||
|
||||
if self.all_loaded then
|
||||
self.menus[self.current_menu]:update(dt)
|
||||
dialog_manager:update(dt)
|
||||
|
||||
-- If the game state changed then trigger a fade out.
|
||||
if self.next_menu ~= self.current_menu and self.fade.done then
|
||||
@@ -101,6 +103,7 @@ end
|
||||
function Menu:draw()
|
||||
if self.all_loaded then
|
||||
self.menus[self.current_menu]:draw()
|
||||
dialog_manager:draw()
|
||||
self.cursor:draw()
|
||||
self.fade:draw()
|
||||
else
|
||||
@@ -108,23 +111,69 @@ function Menu:draw()
|
||||
end
|
||||
end
|
||||
|
||||
function Menu:keypressed(key, code, isrepeat)
|
||||
-- Send events to the active game state if there is no fade active.
|
||||
if Fade.done then
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:keypressed(key, code, isrepeat)
|
||||
else
|
||||
dialog_manager:keypressed(key, code, isrepeat)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Menu:keyreleased(key, code)
|
||||
-- Send events to the active game state if there is no fade active.
|
||||
if Fade.done then
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:keyreleased(key, code)
|
||||
else
|
||||
dialog_manager:keyreleased(key, code)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Menu:textinput(text)
|
||||
-- Send events to the active game state if there is no fade active.
|
||||
if Fade.done then
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:textinput(text)
|
||||
else
|
||||
dialog_manager:textinput(text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Menu:mousemoved(x, y, dx, dy)
|
||||
self.menus[self.current_menu]:mousemoved(x, y, dx, dy)
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:mousemoved(x, y, dx, dy)
|
||||
else
|
||||
dialog_manager:mousemoved(x, y, dx, dy)
|
||||
end
|
||||
self.cursor:mousemoved(x, y, dx, dy)
|
||||
end
|
||||
|
||||
|
||||
function Menu:mousepressed(x, y, btn)
|
||||
if self.fade.done then
|
||||
self.menus[self.current_menu]:mousepressed(x, y, btn)
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:mousepressed(x, y, btn)
|
||||
else
|
||||
dialog_manager:mousepressed(x, y, btn)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Menu:mousereleased(x, y, btn)
|
||||
if self.fade.done then
|
||||
self.menus[self.current_menu]:mousereleased(x, y, btn)
|
||||
if dialog_manager:empty() then
|
||||
self.menus[self.current_menu]:mousereleased(x, y, btn)
|
||||
else
|
||||
dialog_manager:mousereleased(x, y, btn)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,13 +6,17 @@ local make_class = require 'src.utils.classes'
|
||||
local constants = require 'src.gstates.menus.const'
|
||||
local settings = require 'src.utils.settings'
|
||||
local sound_manager = require 'src.sound.sndmngr'
|
||||
local assets = require 'src.utils.asstmngr'
|
||||
local BaseMenu = require 'src.gstates.menus.base'
|
||||
local Color = require 'src.utils.color'
|
||||
local HBox = require 'src.ui.hbox'
|
||||
local Label = require 'src.ui.label'
|
||||
local TextButton = require 'src.ui.textbtn'
|
||||
local TextInput = require 'src.ui.textinpt'
|
||||
local Checkbox = require 'src.ui.chkbox'
|
||||
local Bar = require 'src.ui.bar'
|
||||
local Dialog = require 'src.ui.dialog'
|
||||
local Font = require 'src.ui.font'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@@ -29,11 +33,15 @@ local OptionsMenu = make_class(BaseMenu)
|
||||
function OptionsMenu:_init(parent, title_font, button_font)
|
||||
BaseMenu._init(self, parent, "Options Menu", constants.OPTIONS_MENU, 'imgs/cpu.png')
|
||||
|
||||
self.subtitle_font = Font('fonts/BBrick.ttf', 25)
|
||||
|
||||
-- Create UI elements of the menu.
|
||||
self.container:add(Label(nil, nil, 'Options', title_font, Color(215, 0, 0), true))
|
||||
|
||||
-- Permadeath checkbox.
|
||||
local box = HBox()
|
||||
box:add(Label(nil, nil, 'Enable Permadeath', button_font))
|
||||
|
||||
box:add(Label(nil, nil, 'Enable Permadeath: ', button_font))
|
||||
box:add(Checkbox(
|
||||
function()
|
||||
settings.permadeath = not settings.permadeath
|
||||
@@ -43,14 +51,77 @@ function OptionsMenu:_init(parent, title_font, button_font)
|
||||
end,
|
||||
17,
|
||||
15))
|
||||
|
||||
self.container:add(box)
|
||||
|
||||
box = HBox()
|
||||
box:add(Label(nil, nil, 'Controls', button_font))
|
||||
self.container:add(box)
|
||||
-- Control binding dialog.
|
||||
local dlg = Dialog('imgs/tchcmp1.png', nil, 15, nil, nil, button_font)
|
||||
|
||||
dlg:add(Label(nil, nil, 'Set Controls', self.subtitle_font, Color(215, 0, 0), true))
|
||||
|
||||
box = HBox()
|
||||
box:add(Label(nil, nil, 'Sound Volume', button_font))
|
||||
box.spacing = 30
|
||||
-- text, font, x, y, callback, value, float, base_col, sel_color, press_col
|
||||
box:add(TextInput('Step Forw.',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.forward = v end,
|
||||
function() return settings.forward end))
|
||||
box:add(TextInput('Step Back',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.backward = v end,
|
||||
function() return settings.backward end))
|
||||
|
||||
dlg:add(box)
|
||||
|
||||
box = HBox()
|
||||
box.spacing = 40
|
||||
box:add(TextInput('Step Left',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.stepleft = v end,
|
||||
function() return settings.stepleft end))
|
||||
box:add(TextInput('Step Right',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.stepright = v end,
|
||||
function() return settings.stepright end))
|
||||
|
||||
dlg:add(box)
|
||||
|
||||
box = HBox()
|
||||
box.spacing = 42
|
||||
box:add(TextInput('Turn Left',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.turnleft = v end,
|
||||
function() return settings.turnleft end))
|
||||
box:add(TextInput('Turn Right',
|
||||
button_font,
|
||||
nil, nil,
|
||||
function(v) settings.turnright = v end,
|
||||
function() return settings.turnright end))
|
||||
|
||||
dlg:add(box)
|
||||
|
||||
box = HBox()
|
||||
|
||||
box:add(TextButton(
|
||||
'Set Controls',
|
||||
button_font,
|
||||
nil,
|
||||
nil,
|
||||
function()
|
||||
dlg:show()
|
||||
end))
|
||||
|
||||
self.container:add(box)
|
||||
|
||||
-- Sound volume bar.
|
||||
box = HBox()
|
||||
|
||||
box:add(Label(nil, nil, 'Sound Volume: ', button_font))
|
||||
box:add(Bar(
|
||||
function(v)
|
||||
settings.soundvol = math.ceil(v)
|
||||
@@ -59,12 +130,15 @@ function OptionsMenu:_init(parent, title_font, button_font)
|
||||
return settings.soundvol
|
||||
end,
|
||||
0, 100,
|
||||
175, 15))
|
||||
170, 15))
|
||||
|
||||
self.container:add(box)
|
||||
|
||||
-- Music volume bar.
|
||||
box = HBox()
|
||||
box.spacing = 13
|
||||
box:add(Label(nil, nil, 'Music Volume', button_font))
|
||||
|
||||
box:add(Label(nil, nil, 'Music Volume: ', button_font))
|
||||
box:add(Bar(
|
||||
function(v)
|
||||
settings.musicvol = math.ceil(v)
|
||||
@@ -74,9 +148,11 @@ function OptionsMenu:_init(parent, title_font, button_font)
|
||||
return settings.musicvol
|
||||
end,
|
||||
0, 100,
|
||||
175, 15))
|
||||
170, 15))
|
||||
|
||||
self.container:add(box)
|
||||
|
||||
-- Back button.
|
||||
box = HBox()
|
||||
box:add(TextButton(
|
||||
'Go Back',
|
||||
@@ -88,6 +164,10 @@ function OptionsMenu:_init(parent, title_font, button_font)
|
||||
parent.next_menu = constants.MAIN_MENU
|
||||
end))
|
||||
self.container:add(box)
|
||||
|
||||
-- Register the dialog with the asset manager.
|
||||
assets:register(self.name, dlg)
|
||||
assets:register(self.name, self.subtitle_font)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ local Bar = make_class(UIElement)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function Bar:_init(callback, val_fn, min, max, w, h, color, sel_color, press_col, float, x, y)
|
||||
UIElement._init(self, x, y, float)
|
||||
UIElement._init(self, x, y, float, false)
|
||||
self.callback = callback
|
||||
self.val_fn = val_fn
|
||||
self.min = min
|
||||
@@ -44,17 +44,25 @@ end
|
||||
function Bar:draw()
|
||||
local color = self.callback == nil and self.disbl_col or ((self.pressed and self.press_col) or ((self.selected and self.sel_color) or self.base_col))
|
||||
|
||||
-- Convert the variable's value to the [0, 1] space.
|
||||
local v = (self.val_fn() + math.abs(self.min)) / (self.max + math.abs(self.min))
|
||||
|
||||
love.graphics.setColor(color.r, color.g, color.b)
|
||||
|
||||
-- Render the bar's outline.
|
||||
love.graphics.rectangle('line', self.x, self.y, self.w, self.h)
|
||||
|
||||
-- Render the bar's content using the [0, 1] value as a proportion of the bar's width.
|
||||
love.graphics.rectangle('fill', self.x, self.y, self.w * v, self.h)
|
||||
love.graphics.setColor()
|
||||
end
|
||||
|
||||
|
||||
function Bar:_mouse2bar(x)
|
||||
-- Take the x coord to the [0, 1] space, with clamping.
|
||||
local v = math.max(math.min(((x - self.x) / self.w), 1.0), 0.0)
|
||||
|
||||
-- Convert the value to a horizontal bar coordinate and return it.
|
||||
return (v * (self.max + math.abs(self.min))) - self.min
|
||||
end
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ local UIElement = require 'src.ui.element'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Button: UIElement
|
||||
local Button = make_class(UIElement)
|
||||
|
||||
|
||||
@@ -18,8 +19,12 @@ local Button = make_class(UIElement)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param callback function
|
||||
---@param float boolean
|
||||
function Button:_init(x, y, callback, float)
|
||||
UIElement._init(self, x, y, float)
|
||||
UIElement._init(self, x, y, float, false)
|
||||
self.selected = false
|
||||
self.pressed = false
|
||||
self.was_pressed = false
|
||||
|
||||
117
src/ui/dialog.lua
Normal file
117
src/ui/dialog.lua
Normal file
@@ -0,0 +1,117 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Imports
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local love = require 'love'
|
||||
local make_class = require 'src.utils.classes'
|
||||
local dialog_manager = require 'src.ui.dlgmngr'
|
||||
local VBox = require 'src.ui.vbox'
|
||||
local Sprite = require 'src.graphics.sprite'
|
||||
local TextButton = require 'src.ui.textbtn'
|
||||
local HBox = require 'src.ui.hbox'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local Dialog = make_class(VBox)
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function Dialog:_init(bckg, spacing, padding, close_btn, accept_btn, font)
|
||||
VBox._init(self, nil, nil, nil, nil, spacing, false)
|
||||
self.spacing = spacing ~= nil and spacing or 10
|
||||
self.padding = padding ~= nil and padding or 15
|
||||
self.background = Sprite(bckg)
|
||||
self.shown = false
|
||||
|
||||
local close = nil
|
||||
|
||||
if close_btn ~= nil then
|
||||
close = close_btn
|
||||
else
|
||||
close = TextButton(
|
||||
'Close',
|
||||
font,
|
||||
nil,
|
||||
nil,
|
||||
function()
|
||||
self:hide()
|
||||
end)
|
||||
end
|
||||
|
||||
local accept = nil
|
||||
if accept_btn ~= nil then accept = accept_btn end
|
||||
|
||||
-- Create a container for the close and accept button and add them.
|
||||
local box = HBox(nil, nil, nil, nil, 10, true)
|
||||
box:add(close)
|
||||
|
||||
if accept ~= nil then box:add(accept) end
|
||||
|
||||
self.elements[9001] = box
|
||||
end
|
||||
|
||||
|
||||
function Dialog:add(element)
|
||||
table.insert(self.elements, element)
|
||||
end
|
||||
|
||||
|
||||
function Dialog:load()
|
||||
self.background:load()
|
||||
self:set_dimensions()
|
||||
VBox.load(self)
|
||||
end
|
||||
|
||||
|
||||
function Dialog:set_dimensions()
|
||||
self.w = self.background.sprite:getWidth()
|
||||
self.h = self.background.sprite:getHeight()
|
||||
|
||||
-- Center the dialog on the screen.
|
||||
self.x = (320 - self.w) / 2
|
||||
self.y = (200 - self.h) / 2
|
||||
|
||||
self.background.x = self.x
|
||||
self.background.y = self.y
|
||||
|
||||
-- Add padding.
|
||||
self.x = self.x + self.padding
|
||||
self.y = self.y + self.padding / 2
|
||||
end
|
||||
|
||||
|
||||
function Dialog:draw()
|
||||
love.graphics.setColor(0, 0, 0)
|
||||
love.graphics.rectangle('line', self.x - self.padding - 1, self.y - (self.padding / 2) - 1, self.w + 2, self.h + 2)
|
||||
love.graphics.setColor()
|
||||
|
||||
self.background:draw()
|
||||
VBox.draw(self)
|
||||
end
|
||||
|
||||
|
||||
function Dialog:show()
|
||||
if not self.shown then
|
||||
dialog_manager:add(self)
|
||||
self.shown = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Dialog:hide()
|
||||
dialog_manager:remove(self)
|
||||
self.shown = false
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Module return
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return Dialog
|
||||
104
src/ui/dlgmngr.lua
Normal file
104
src/ui/dlgmngr.lua
Normal file
@@ -0,0 +1,104 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Imports
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local make_class = require 'src.utils.classes'
|
||||
local Drawable = require 'src.graphics.drawable'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local DialogManager = make_class(Drawable)
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function DialogManager:_init()
|
||||
Drawable._init(self)
|
||||
self.dialogs = {}
|
||||
self.count = 0
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:add(dialog)
|
||||
self.dialogs[dialog] = true
|
||||
self.count = self.count + 1
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:remove(dialog)
|
||||
self.dialogs[dialog] = nil
|
||||
self.count = math.max(self.count - 1, 0)
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:empty()
|
||||
return self.count == 0
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:update(dt)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:draw()
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:draw()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:keypressed(key, code, isrepeat)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:keypressed(key, code, isrepeat)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:textinput(text)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:textinput(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:keyreleased(key, code)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:keyreleased(key, code)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:mousemoved(x, y, dx, dy)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:mousemoved(x, y, dx, dy)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:mousepressed(x, y, btn)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:mousepressed(x, y, btn)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DialogManager:mousereleased(x, y, btn)
|
||||
for d, _ in pairs(self.dialogs) do
|
||||
d:mousereleased(x, y, btn)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Module return
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return DialogManager()
|
||||
@@ -6,11 +6,18 @@ local make_class = require 'src.utils.classes'
|
||||
local Asset = require 'src.utils.asset'
|
||||
local Drawable = require 'src.graphics.drawable'
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local focused_element = nil
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class UIElement: Drawable, Asset
|
||||
local UIElement = make_class(Drawable, Asset)
|
||||
|
||||
|
||||
@@ -18,13 +25,18 @@ local UIElement = make_class(Drawable, Asset)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function UIElement:_init(x, y, float)
|
||||
---@param x integer
|
||||
---@param y integer
|
||||
---@param float boolean
|
||||
---@param focusable boolean
|
||||
function UIElement:_init(x, y, float, focusable)
|
||||
Asset._init(self)
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = nil
|
||||
self.h = nil
|
||||
self.float_right = float and float or false
|
||||
self.focusable = focusable ~= nil and focusable or false
|
||||
end
|
||||
|
||||
|
||||
@@ -34,7 +46,6 @@ function UIElement:set_dimensions()
|
||||
end
|
||||
|
||||
|
||||
|
||||
function UIElement:load()
|
||||
end
|
||||
|
||||
@@ -48,6 +59,24 @@ function UIElement:is_loaded()
|
||||
end
|
||||
|
||||
|
||||
function UIElement:focus()
|
||||
if self.focusable then
|
||||
focused_element = self
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function UIElement:blur()
|
||||
if self.focusable and focused_element == self then
|
||||
focused_element = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function UIElement:is_focused()
|
||||
return self.focusable and focused_element == self
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Module return
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -10,6 +10,7 @@ local Asset = require 'src.utils.asset'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Font: Asset
|
||||
-- Font is a simple wrapper around Löve's own Font class to allow for
|
||||
-- easy loading/unloading and automatically checking if it's is valid
|
||||
-- before using it.
|
||||
@@ -20,6 +21,8 @@ local Font = make_class(Asset)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@param file_name string
|
||||
---@param size number
|
||||
function Font:_init(file_name, size)
|
||||
self.file_name = string.format('assets/%s', file_name)
|
||||
self.size = (size ~= nil and size) or 20
|
||||
|
||||
@@ -10,6 +10,7 @@ local Layout = require 'src.ui.layout'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class HBox: Layout
|
||||
local HBox = make_class(Layout)
|
||||
|
||||
|
||||
@@ -17,8 +18,8 @@ local HBox = make_class(Layout)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function HBox:_init(x, y, w, h, spacing)
|
||||
Layout._init(self, x, y, w, h, spacing)
|
||||
function HBox:_init(x, y, w, h, spacing, float)
|
||||
Layout._init(self, x, y, w, h, spacing, float)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ local Color = require 'src.utils.color'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Label: UIElement
|
||||
local Label = make_class(UIElement)
|
||||
|
||||
|
||||
@@ -19,8 +20,14 @@ local Label = make_class(UIElement)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param text string
|
||||
---@param font Font
|
||||
---@param color Color
|
||||
---@param float boolean
|
||||
function Label:_init(x, y, text, font, color, float)
|
||||
UIElement._init(self, x, y, float)
|
||||
UIElement._init(self, x, y, float, false)
|
||||
self.text = text
|
||||
self.font = font
|
||||
self.color = color ~= nil and color or Color(255, 255, 255)
|
||||
@@ -34,9 +41,7 @@ end
|
||||
|
||||
|
||||
function Label:load()
|
||||
if not self.font:is_loaded() then
|
||||
self.font:load()
|
||||
end
|
||||
self.font:load()
|
||||
|
||||
-- If the label's size has not been computed then do it.
|
||||
if self.w == nil or self.h == nil then self:set_dimensions() end
|
||||
|
||||
@@ -10,6 +10,7 @@ local UIElement = require 'src.ui.element'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Layout: UIElement
|
||||
local Layout = make_class(UIElement)
|
||||
|
||||
|
||||
@@ -18,7 +19,7 @@ local Layout = make_class(UIElement)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function Layout:_init(x, y, w, h, spacing, float)
|
||||
UIElement._init(self, x, y, float)
|
||||
UIElement._init(self, x, y, float, false)
|
||||
self.x = x ~= nil and x or 0
|
||||
self.y = y ~= nil and y or 0
|
||||
self.w = w
|
||||
@@ -68,6 +69,27 @@ function Layout:draw()
|
||||
end
|
||||
|
||||
|
||||
function Layout:keypressed(key, code, isrepeat)
|
||||
for _, v in pairs(self.elements) do
|
||||
v:keypressed(key, code, isrepeat)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Layout:textinput(text)
|
||||
for _, v in pairs(self.elements) do
|
||||
v:textinput(text)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Layout:keyreleased(key, code)
|
||||
for _, v in pairs(self.elements) do
|
||||
v:keyreleased(key, code)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Layout:mousemoved(x, y, dx, dy)
|
||||
for _, v in pairs(self.elements) do
|
||||
v:mousemoved(x, y, dx, dy)
|
||||
|
||||
118
src/ui/textinpt.lua
Normal file
118
src/ui/textinpt.lua
Normal file
@@ -0,0 +1,118 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Imports
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local love = require 'love'
|
||||
local make_class = require 'src.utils.classes'
|
||||
local collisions = require 'src.utils.colls'
|
||||
local UIElement = require 'src.ui.element'
|
||||
local Color = require 'src.utils.color'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class CharInput: UIElement
|
||||
local TextInput = make_class(UIElement)
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@param text string
|
||||
---@param font Font
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param callback function
|
||||
---@param value function
|
||||
---@param float boolean
|
||||
---@param base_col Color
|
||||
---@param sel_color Color
|
||||
---@param press_col Color
|
||||
function TextInput:_init(text, font, x, y, callback, value, float, base_col, sel_color, press_col)
|
||||
UIElement._init(self, x, y, float, true)
|
||||
self.callback = callback
|
||||
self.value = value
|
||||
self.font = font
|
||||
self.text = text
|
||||
self.base_col = base_col ~= nil and base_col or Color(255, 255, 255)
|
||||
self.sel_color = sel_color ~= nil and sel_color or Color(215, 0, 0)
|
||||
self.press_col = press_col ~= nil and press_col or Color(99, 99, 139)
|
||||
self.disbl_col = Color(95, 63, 75)
|
||||
self.selected = false
|
||||
self.pressed = false
|
||||
end
|
||||
|
||||
|
||||
function TextInput:load()
|
||||
self.font:load()
|
||||
|
||||
-- If the label's size has not been computed then do it.
|
||||
if self.w == nil or self.h == nil then self:set_dimensions() end
|
||||
end
|
||||
|
||||
|
||||
function TextInput:unload()
|
||||
self.font:unload()
|
||||
end
|
||||
|
||||
|
||||
function TextInput:is_loaded()
|
||||
return self.font:is_loaded() and self.w ~= nil and self.h ~= nil
|
||||
end
|
||||
|
||||
|
||||
function TextInput:set_dimensions()
|
||||
self.w = self.font:get_width(self.text .. 'm')
|
||||
self.h = self.font:get_height(self.text)
|
||||
end
|
||||
|
||||
|
||||
function TextInput:draw()
|
||||
local color = self.callback == nil and self.disbl_col or (((self.pressed or self:is_focused()) and self.press_col) or ((self.selected and self.sel_color) or self.base_col))
|
||||
|
||||
love.graphics.setColor(color.r, color.g, color.b)
|
||||
self.font:set()
|
||||
|
||||
if self:is_focused() then
|
||||
love.graphics.print(self.text .. ': ?', self.x, self.y)
|
||||
else
|
||||
love.graphics.print(self.text .. ': ' .. self.value(), self.x, self.y)
|
||||
end
|
||||
|
||||
self.font:unset()
|
||||
love.graphics.setColor()
|
||||
end
|
||||
|
||||
|
||||
function TextInput:mousemoved(x, y)
|
||||
-- Select if the pointer is inside the button's bounding rect.
|
||||
self.selected = collisions.point_in_square(x, y, self.x, self.y, self.w, self.h)
|
||||
end
|
||||
|
||||
|
||||
function TextInput:mousepressed(_, _, btn)
|
||||
-- If the pointer was inside the button when it was pressed then mark the button as pressed.
|
||||
if btn == 0 and self.selected then
|
||||
self:focus()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function TextInput:keypressed(key)
|
||||
if self:is_focused() then
|
||||
if #key == 1 then
|
||||
if self.callback ~= nil then self.callback(key) end
|
||||
self:blur()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Module return
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return TextInput
|
||||
@@ -10,6 +10,7 @@ local Layout = require 'src.ui.layout'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class VBox: Layout
|
||||
local VBox = make_class(Layout)
|
||||
|
||||
|
||||
@@ -17,8 +18,8 @@ local VBox = make_class(Layout)
|
||||
-- Class methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function VBox:_init(x, y, w, h, spacing)
|
||||
Layout._init(self, x, y, w, h, spacing)
|
||||
function VBox:_init(x, y, w, h, spacing, float)
|
||||
Layout._init(self, x, y, w, h, spacing, float)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ local make_class = require 'src.utils.classes'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Asset
|
||||
local Asset = make_class()
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
-- Methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
-- Code from http://lua-users.org/wiki/ObjectOrientationTutorial
|
||||
--- Code from http://lua-users.org/wiki/ObjectOrientationTutorial
|
||||
---@param ... table Optional base classes
|
||||
---@return table cls A class definition
|
||||
local function make_class(...)
|
||||
-- "cls" is the new class
|
||||
local cls, bases = {}, {...}
|
||||
|
||||
@@ -9,6 +9,7 @@ local make_class = require 'src.utils.classes'
|
||||
-- Class definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
---@class Color
|
||||
local Color = make_class()
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
local love = require 'love'
|
||||
local magiclines = require 'src.utils.mgclines'
|
||||
local make_class = require 'src.utils.classes'
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
@@ -17,25 +18,29 @@ local SETTINGS_PATH = 'settings.ini'
|
||||
-- Module definitions
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local settings = {
|
||||
-- Default setting values.
|
||||
permadeath = true,
|
||||
forward = 'w',
|
||||
backward = 's',
|
||||
stepleft = 'a',
|
||||
stepright = 'd',
|
||||
turnleft = 'q',
|
||||
turnright = 'e',
|
||||
musicvol = 75,
|
||||
soundvol = 100,
|
||||
}
|
||||
---@class Settings
|
||||
local Settings = make_class()
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- Private module methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function settings:_parse_settings_str(s)
|
||||
function Settings:_init()
|
||||
-- Default setting values.
|
||||
self.permadeath = true
|
||||
self.forward = 'w'
|
||||
self.backward = 's'
|
||||
self.stepleft = 'a'
|
||||
self.stepright = 'd'
|
||||
self.turnleft = 'q'
|
||||
self.turnright = 'e'
|
||||
self.musicvol = 75
|
||||
self.soundvol = 100
|
||||
end
|
||||
|
||||
|
||||
function Settings:_parse_settings_str(s)
|
||||
-- For each line in the data string.
|
||||
for line in magiclines(s) do
|
||||
-- Check if the line matches a key=value pair
|
||||
@@ -67,7 +72,7 @@ function settings:_parse_settings_str(s)
|
||||
end
|
||||
|
||||
|
||||
function settings:_get_settings_str()
|
||||
function Settings:_get_settings_str()
|
||||
-- Start with the settings category.
|
||||
local s = '[settings]\n'
|
||||
|
||||
@@ -84,7 +89,7 @@ function settings:_get_settings_str()
|
||||
end
|
||||
|
||||
|
||||
function settings:_open_or_create()
|
||||
function Settings:_open_or_create()
|
||||
if not love.filesystem.exists(SETTINGS_PATH) then
|
||||
-- If the settings file doesn't exist then create it with the default values.
|
||||
local setts = self:_get_settings_str()
|
||||
@@ -106,14 +111,14 @@ end
|
||||
-- Public module methods
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
function settings:load_settings()
|
||||
function Settings:load_settings()
|
||||
-- Obtain the settings data and parse it.
|
||||
local s = self:_open_or_create()
|
||||
self:_parse_settings_str(s)
|
||||
end
|
||||
|
||||
|
||||
function settings:save_settings()
|
||||
function Settings:save_settings()
|
||||
if not love.filesystem.exists(SETTINGS_PATH) or love.filesystem.isFile(SETTINGS_PATH) then
|
||||
-- If the settings file doesn't exist or it exists and is a file then save the current data.
|
||||
love.filesystem.write(SETTINGS_PATH, self:_get_settings_str())
|
||||
@@ -128,4 +133,4 @@ end
|
||||
-- Module return
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
return settings
|
||||
return Settings()
|
||||
|
||||
Reference in New Issue
Block a user