require 'tablefuncs' require 'gridpoint' -- Interactive game object ---@class Line ---@field startpoint GridPoint ---@field endpoint GridPoint ---@field points GridPoint[] ---@field color Color Line = { startpoint = GridPoint:new( GridPoint:coords() ), endpoint = GridPoint:new( GridPoint:coords() ), points = { }, color = Color.red } -- Factory function ---@param startpoint GridPoint ---@param endpoint GridPoint ---@param color Color ---@return Line function Line:new( startpoint, endpoint, color ) local line = { startpoint = startpoint or self.startpoint, endpoint = endpoint or self.endpoint, points = { startpoint or self.startpoint }, color = color or self.color } setmetatable( line, { __index = self } ) return line end -- Push point to the end of points stack ---@param point GridPoint function Line:push( point ) table.insert( self.points, point ) end -- Pop point from points stack ---@return GridPoint function Line:pop() return table.remove( self.points ) end -- Draw line with connected dots 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 ) local ex, ey = self.endpoint:globalCoords() love.graphics.circle( "fill", ex, ey, Config.linePointRadius ) if #self.points <= 1 then love.graphics.setColor( Color.white ) return end -- Draw line local points = {} for _, point in ipairs( self.points ) do local x, y = point:globalCoords() table.insert( points, x ) table.insert( points, y ) end love.graphics.line( points ) love.graphics.setColor( Color.white ) end -- Clear points function Line:clear() for k, _ in pairs( self.points ) do self.points[k] = nil end end -- Swap startpoint and endpoint function Line:reverse() local swap = self.startpoint self.startpoint = self.endpoint self.endpoint = swap self:push( self.startpoint ) end -- Check if line has the exact point ---@param point GridPoint ---@return boolean function Line:has( point ) return TableHas( self.points, point, function( value, innervalue ) return innervalue:equals( value ) end ) end