added menu handler

This commit is contained in:
Alexey 2025-10-22 13:45:09 +03:00
commit d7dcda1ada
3 changed files with 150 additions and 25 deletions

View file

@ -7,6 +7,7 @@ require 'tablefuncs'
---@field cellSize number Size of each grid cell ---@field cellSize number Size of each grid cell
---@field lineStyle string love2d line style setting ---@field lineStyle string love2d line style setting
---@field lineWidth number love2d line width setting ---@field lineWidth number love2d line width setting
---@field menuLineWidth number love2d line width for buttons
---@field dragSensivity number drag sensivity, px ---@field dragSensivity number drag sensivity, px
Config = { Config = {
pointRadius = 0.3, pointRadius = 0.3,
@ -17,6 +18,7 @@ Config = {
lineStyle = "smooth", lineStyle = "smooth",
lineWidth = 0.1, lineWidth = 0.1,
menuLineWidth = 4,
dragSensivity = 5 dragSensivity = 5
} }

View file

@ -4,56 +4,56 @@ require 'line'
require 'mouse' require 'mouse'
require 'levelhandler' require 'levelhandler'
require 'button' require 'button'
require 'menu'
Input = require 'input' Input = require 'input'
InMenu = true
local function updateCellSize()
local width, height = love.graphics.getDimensions()
local gridX, gridY = GameGrid.size:coords();
local isWidthBased = (width / height) / (gridX / gridY)
Config.cellSize = math.floor(isWidthBased and height / gridY or width / gridX)
love.graphics.setLineWidth( Config.cellSize * Config.lineWidth )
end
function love.load() function love.load()
love.window.setMode( 800, 480 ) love.window.setMode( 800, 480 )
local menuButtonReleased = function() InMenu = true
InMenu = false
GameGrid = LevelHandler:first()
updateCellSize()
end
MenuStartButton = Button:new( Point:new( 240, 120 ), Point:new( 320, 80 ), nil, nil, menuButtonReleased )
love.graphics.setLineStyle( Config.lineStyle ) love.graphics.setLineStyle( Config.lineStyle )
end end
function love.update( dt ) function love.update( dt )
InMenu = Menu.current_state ~= MenuStateIndex.hidden
Mouse:update() Mouse:update()
Input:update() Input:update()
if InMenu then
MenuStartButton:update( dt, Point:new( Mouse.x, Mouse.y ), Mouse.pressed )
else
if Input:actionReleased( 'exit' ) then
love.event.quit()
end
local exit = Input:actionReleased( 'exit' )
if InMenu then
Menu:update( dt, Point:new( Mouse.x, Mouse.y ), Mouse.pressed )
else
if Input:actionReleased( 'nextlevel' ) then if Input:actionReleased( 'nextlevel' ) then
if GameGrid:isCompleted() then if GameGrid:isCompleted() then
GameGrid = LevelHandler:next() GameGrid = LevelHandler:next()
updateCellSize() Menu.updateCellSize()
end end
end end
end end
-- Switch menu state or exit
if exit then
if not InMenu then
Menu.current_state = MenuStateIndex.pause
elseif Menu.current_state == MenuStateIndex.start then
love.event.quit()
elseif Menu.current_state == MenuStateIndex.pause then
Menu.current_state = MenuStateIndex.hidden
elseif Menu.current_state == MenuStateIndex.levels then
Menu.current_state = MenuStateIndex.start
end
end
end end
function love.draw() function love.draw()
if InMenu then if InMenu then
MenuStartButton:draw() love.graphics.setLineWidth( Config.menuLineWidth )
Menu:draw()
else else
love.graphics.setLineWidth( Config.cellSize * Config.lineWidth )
GameGrid:draw() GameGrid:draw()
local text = string.format( "%d:%d global\n%d:%d local\n%d:%d from start", Mouse.x, Mouse.y, Mouse.point.x, Mouse.point.y, Mouse.startX - Mouse.x, Mouse.startY - Mouse.y ) local text = string.format( "%d:%d global\n%d:%d local\n%d:%d from start", Mouse.x, Mouse.y, Mouse.point.x, Mouse.point.y, Mouse.startX - Mouse.x, Mouse.startY - Mouse.y )

123
menu.lua Normal file
View file

@ -0,0 +1,123 @@
require 'config'
require 'button'
-- Menu state class
---@class MenuState
---@field buttons Button[]
MenuState = {
buttons = {}
}
-- Factory function
---@param buttons Button[] | nil
---@return MenuState
function MenuState:new( buttons )
local state = {
buttons = buttons or MenuState.buttons
}
setmetatable( state, { __index = self } )
return state
end
-- Draw buttons
function MenuState:draw()
for _, button in ipairs(self.buttons) do
button:draw()
end
end
-- Update buttons
---@param dt number
---@param point Point
---@param pressed boolean
function MenuState:update( dt, point, pressed )
for _, button in pairs(self.buttons) do
button:update( dt, point, pressed )
end
end
---@enum MenuStateIndex
MenuStateIndex = {
start = 'start',
pause = 'pause',
levels = 'levels',
hidden = 'hidden'
}
local startButton = Button:new(
Point:new( 240, 120 ),
Point:new( 320, 80 ),
nil,
nil,
function()
Menu.current_state = MenuStateIndex.hidden
GameGrid = LevelHandler:first()
Menu.updateCellSize()
end
)
local exitToMenuButton = Button:new(
Point:new( 240, 200 ),
Point:new( 320, 80 ),
nil,
nil,
function()
Menu.current_state = MenuStateIndex.start
end
)
local exitGameButton = Button:new(
Point:new( 240, 240 ),
Point:new( 320, 80 ),
nil,
nil,
function()
love.event.quit()
end
)
-- Menu handler
---@class Menu
---@field states MenuState[]
---@field current_state MenuStateIndex
Menu = {
states = {
-- Main menu
[MenuStateIndex.start] = MenuState:new({
startButton, exitGameButton
}),
-- Pause menu
[MenuStateIndex.pause] = MenuState:new({
exitToMenuButton
}),
-- Level selector
[MenuStateIndex.levels] = MenuState:new({
}),
-- Empty state
[MenuStateIndex.hidden] = MenuState:new()
},
current_state = MenuStateIndex.start
}
-- Draw current state
function Menu:draw()
self.states[self.current_state]:draw()
end
-- Update current state
---@param dt number
---@param point Point
---@param pressed boolean
function Menu:update( dt, point, pressed )
self.states[self.current_state]:update( dt, point, pressed )
end
function Menu.updateCellSize()
local width, height = love.graphics.getDimensions()
local gridX, gridY = GameGrid.size:coords();
local isWidthBased = (width / height) / (gridX / gridY)
Config.cellSize = math.floor(isWidthBased and height / gridY or width / gridX)
love.graphics.setLineWidth( Config.cellSize * Config.lineWidth )
end