Compare commits

..

2 commits

Author SHA1 Message Date
319a642688 UI button and main menu beginning 2025-07-04 13:39:17 +03:00
293f529613 Scaling drawing 2025-07-03 15:11:46 +03:00
8 changed files with 156 additions and 32 deletions

83
button.lua Normal file
View file

@ -0,0 +1,83 @@
require 'point'
-- Clickable UI button
---@class Button
---@field position Point
---@field size Point
---@field prevPressed boolean
---@field lastPressed boolean
Button = {
position = Point:new( 1, 1 ),
size = Point:new( 1, 1 ),
prevPressed = false,
lastPressed = false
}
-- Factory function
---@param position Point | nil
---@param size Point | nil
---@param pressed function | nil
---@param held function | nil
---@param released function | nil
---@return Button
function Button:new( position, size, pressed, held, released )
local button = {
position = position or Button.position,
size = size or Button.size,
prevPressed = false,
lastPressed = false,
pressed = pressed or Button.pressed,
held = held or Button.held,
released = released or Button.released
}
setmetatable( button, { __index = self } )
return button
end
-- Called when button just clicked
function Button:pressed() end
-- Called when button is held
---@param dt number
function Button:held( dt ) dt = dt end
-- Called when button is just unclicked
function Button:released() end
-- Drawing function
function Button:draw()
local x, y = self.position:coords()
local w, h = self.size:coords()
love.graphics.rectangle( 'line', x, y, w, h )
end
-- Check if given point is in bounds of button
---@param point Point
---@return boolean
function Button:checkPoint( point )
local px, py = point:coords()
local sx, sy = self.position:coords()
local ex, ey = self.position:coords()
ex = ex + sx
ey = ey + sy
return px >= sx and px <= ex and py >= sy and py <= ey
end
-- Changing states and calls appropriate functions
---@param dt number
---@param point Point
function Button:update( dt, point, pressed )
self.prevPressed = self.lastPressed
self.lastPressed = pressed
if self.lastPressed and not self.prevPressed then
local inBounds = self:checkPoint( point )
if inBounds then
self:pressed()
end
elseif self.lastPressed and self.prevPressed then
self:held( dt )
elseif not self.lastPressed and self.prevPressed then
self:released()
end
end

View file

@ -2,21 +2,21 @@ require 'tablefuncs'
-- Global config table
---@class Config
---@field pointRadius number Radius of each grid point
---@field linePointRadius number Radius of line start/end point
---@field pointRadius number Radius of each grid point, relative to cellSize
---@field linePointRadius number Radius of line start/end points, relative to cellSize
---@field cellSize number Size of each grid cell
---@field lineStyle string love2d line style setting
---@field lineWidth number love2d line width setting
---@field dragSensivity number drag sensivity, px
Config = {
pointRadius = 7,
pointRadius = 0.3,
linePointRadius = 10,
linePointRadius = 0.4,
cellSize = 30,
lineStyle = "smooth",
lineWidth = 5,
lineWidth = 0.1,
dragSensivity = 5
}

View file

@ -12,7 +12,7 @@ Grid = {
-- Factory function
---@param size Point
---@returns Grid
---@return Grid
function Grid:new( size )
local grid = {
lines = {},
@ -40,7 +40,7 @@ function Grid:draw()
for y = 1, self.size.y do
local px, py = x * Config.cellSize, y * Config.cellSize
love.graphics.circle( "fill", px - Config.cellSize / 2, py - Config.cellSize / 2, Config.pointRadius)
love.graphics.circle( "fill", px - Config.cellSize / 2, py - Config.cellSize / 2, Config.cellSize * Config.pointRadius)
end
end
-- Draw lines

View file

@ -6,7 +6,7 @@ require 'makegrid'
---@field current integer
LevelHandler = {
levels = {
'test2', 'test'
'test3', 'test2', 'test'
},
current = 1,
}

9
levels/test3.lua Normal file
View file

@ -0,0 +1,9 @@
return {
width = 6,
height = 6,
lines = {
{ 5, 4, 2, 2, "green" },
{ 2, 5, 4, 1, "red" },
{ 2, 4, 5, 1, "blue" }
}
}

View file

@ -51,9 +51,9 @@ function Line:draw()
love.graphics.setColor( self.color )
-- Draw start and end points (should look like rings)
local sx, sy = self.startpoint:globalCoords()
love.graphics.circle( "fill", sx, sy, Config.linePointRadius )
love.graphics.circle( "fill", sx, sy, Config.cellSize * Config.linePointRadius )
local ex, ey = self.endpoint:globalCoords()
love.graphics.circle( "fill", ex, ey, Config.linePointRadius )
love.graphics.circle( "fill", ex, ey, Config.cellSize * Config.linePointRadius )
if #self.points <= 1 then
love.graphics.setColor( Color.white )
return

View file

@ -3,44 +3,71 @@ require 'point'
require 'line'
require 'mouse'
require 'levelhandler'
require 'button'
Input = require 'input'
function love.load()
love.graphics.setLineStyle( Config.lineStyle )
love.graphics.setLineWidth( Config.lineWidth )
InMenu = true
GameGrid = LevelHandler:first()
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()
love.window.setMode( 800, 480 )
local menuButtonReleased = function()
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 )
end
function love.update( dt )
Mouse: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
if Input:actionReleased( 'exit' ) then
love.event.quit()
end
if Input:actionReleased( 'nextlevel' ) then
if GameGrid:isCompleted() then
GameGrid = LevelHandler:next()
if Input:actionReleased( 'nextlevel' ) then
if GameGrid:isCompleted() then
GameGrid = LevelHandler:next()
updateCellSize()
end
end
end
end
function love.draw()
GameGrid:draw()
if InMenu then
MenuStartButton:draw()
else
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 )
love.graphics.print( text, 64, 256 )
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 )
love.graphics.print( text, 64, 256 )
if Mouse.dragged then
love.graphics.print( "drag", 64, 300 )
end
if Mouse.lastLine ~= nil then
love.graphics.print( tostring( Mouse.lastLine ), 128, 300 )
end
if Mouse.dragged then
love.graphics.print( "drag", 64, 300 )
end
if Mouse.lastLine ~= nil then
love.graphics.print( tostring( Mouse.lastLine ), 128, 300 )
end
if GameGrid:isCompleted() then
love.graphics.print( "Grid completed. Press space to proceed to next", 64, 320 )
if GameGrid:isCompleted() then
love.graphics.print( "Grid completed. Press space to proceed to next", 64, 320 )
end
end
end

View file

@ -31,6 +31,11 @@ function Mouse:update()
Mouse.lastPoint = Mouse.point
Mouse.lastPressed = Mouse.pressed
Mouse.pressed = love.mouse.isDown( 1 )
if InMenu then
return
end
Mouse.point = GridPoint.snapCoords( Point:new( Mouse.x, Mouse.y ) )
if Mouse.lastLine ~= nil then
local pointsLen = #Mouse.lastLine.points