Almost working from 1st try
This commit is contained in:
commit
c6547c1121
8 changed files with 297 additions and 0 deletions
5
config.lua
Normal file
5
config.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Config = {
|
||||||
|
cellSize = 64,
|
||||||
|
gridOffset = 0,
|
||||||
|
portWidth = 16
|
||||||
|
}
|
||||||
31
gridpoint.lua
Normal file
31
gridpoint.lua
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
require 'point'
|
||||||
|
require 'config'
|
||||||
|
|
||||||
|
-- Point table with grid-based coordinates
|
||||||
|
---@class GridPoint: Point
|
||||||
|
GridPoint = Point
|
||||||
|
|
||||||
|
-- Convert grid x, y to global x, y
|
||||||
|
---@return Point
|
||||||
|
function GridPoint:absolute()
|
||||||
|
return Point:new(
|
||||||
|
self.x * Config.cellSize + Config.gridOffset,
|
||||||
|
self.y * Config.cellSize
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Same as coords, but converted to global coords
|
||||||
|
---@return number, number
|
||||||
|
function GridPoint:globalCoords()
|
||||||
|
return self.x * Config.cellSize - Config.cellSize / 2 + Config.gridOffset,
|
||||||
|
self.y * Config.cellSize - Config.cellSize / 2
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns local coords from global
|
||||||
|
---@param point Point
|
||||||
|
---@return GridPoint
|
||||||
|
function GridPoint.snapCoords( point )
|
||||||
|
local x = math.ceil( (point.x - Config.gridOffset) / Config.cellSize )
|
||||||
|
local y = math.ceil( point.y / Config.cellSize )
|
||||||
|
return GridPoint:new( x, y )
|
||||||
|
end
|
||||||
33
main.lua
Normal file
33
main.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
require 'point'
|
||||||
|
require 'gridpoint'
|
||||||
|
require 'mouse'
|
||||||
|
require 'mechanism'
|
||||||
|
require 'port'
|
||||||
|
|
||||||
|
function love.load()
|
||||||
|
Screenw, Screenh = love.window.getMode()
|
||||||
|
Gridw, Gridh = Screenw / Config.cellSize, Screenh / Config.cellSize
|
||||||
|
local port = Port:new( GridPoint:new(-1, 0), PortRotation.left, { 0.8, 0.8, 0, 1 } )
|
||||||
|
Mecha1 = Mechanism:new( GridPoint:new(5, 5), GridPoint:new(3, 3), { port }, {0.5, 0.5, 0.5, 1} )
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.update( dt )
|
||||||
|
dt = dt
|
||||||
|
Mouse:update()
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.draw()
|
||||||
|
for i = 1, Gridw do
|
||||||
|
love.graphics.line( i * Config.cellSize, 0, i * Config.cellSize, Screenh )
|
||||||
|
end
|
||||||
|
for j = 1, Gridh do
|
||||||
|
love.graphics.line( 0, j * Config.cellSize, Screenw, j * Config.cellSize )
|
||||||
|
end
|
||||||
|
local mx, my = Mouse.point:globalCoords()
|
||||||
|
mx = mx - Config.cellSize / 2
|
||||||
|
my = my - Config.cellSize / 2
|
||||||
|
local mh, mw = Config.cellSize, Config.cellSize
|
||||||
|
love.graphics.rectangle("fill", mx, my, mh, mw)
|
||||||
|
|
||||||
|
Mecha1:draw()
|
||||||
|
end
|
||||||
69
mechanism.lua
Normal file
69
mechanism.lua
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
require 'tablefuncs'
|
||||||
|
require 'gridpoint'
|
||||||
|
require 'port'
|
||||||
|
|
||||||
|
---@param xcorner GridPoint
|
||||||
|
---@param size GridPoint
|
||||||
|
---@return GridPoint
|
||||||
|
local function nextxcorner( xcorner, size )
|
||||||
|
local cornerLookup = {
|
||||||
|
GridPoint:new( 0, 0 ),
|
||||||
|
GridPoint:new( size.x - 1, 0 ),
|
||||||
|
GridPoint:new( size.x - 1, size.y - 1 ),
|
||||||
|
GridPoint:new( size.x - 1, size.y - 1 )
|
||||||
|
}
|
||||||
|
local index = TableFind(cornerLookup, xcorner, function(value) value:equals(xcorner) end)
|
||||||
|
if index < #cornerLookup then
|
||||||
|
index = index + 1
|
||||||
|
else
|
||||||
|
index = 0
|
||||||
|
end
|
||||||
|
return cornerLookup[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
---@class Mechanism
|
||||||
|
---@field position GridPoint
|
||||||
|
---@field size GridPoint
|
||||||
|
---@field xcorner GridPoint
|
||||||
|
---@field ports Port[]
|
||||||
|
---@field color table
|
||||||
|
Mechanism = {
|
||||||
|
position = GridPoint:new( 0, 0 ),
|
||||||
|
size = GridPoint:new( 1, 1 ),
|
||||||
|
xcorner = GridPoint:new( 0, 0 ),
|
||||||
|
ports = {},
|
||||||
|
color = { 0.5, 0.5, 0.5, 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
function Mechanism:new( position, size, ports, color )
|
||||||
|
local mechanism = {
|
||||||
|
position = position or self.position,
|
||||||
|
size = size or self.size,
|
||||||
|
ports = ports or {},
|
||||||
|
color = color or self.color
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable( mechanism, { __index = self } )
|
||||||
|
|
||||||
|
return mechanism
|
||||||
|
end
|
||||||
|
|
||||||
|
function Mechanism:rotateClockwise()
|
||||||
|
self.xcorner = nextxcorner(self.xcorner, self.size)
|
||||||
|
for _, port in ipairs(self.ports) do
|
||||||
|
port:rotateClockwise()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Mechanism:draw()
|
||||||
|
love.graphics.setColor(self.color)
|
||||||
|
local x, y = self.position:globalCoords()
|
||||||
|
x = x - Config.cellSize / 2
|
||||||
|
y = y - Config.cellSize / 2
|
||||||
|
local w, h = self.size:globalCoords()
|
||||||
|
love.graphics.rectangle("fill", x, y, w, h)
|
||||||
|
for _, port in ipairs(self.ports) do
|
||||||
|
local offset = GridPoint:new( self.position.x + self.xcorner.x, self.position.y + self.xcorner.y )
|
||||||
|
port:draw( offset )
|
||||||
|
end
|
||||||
|
end
|
||||||
19
mouse.lua
Normal file
19
mouse.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- TODO: rewrite
|
||||||
|
---@class Mouse
|
||||||
|
---@field x integer
|
||||||
|
---@field y integer
|
||||||
|
---@field point GridPoint
|
||||||
|
Mouse = {
|
||||||
|
x = 0,
|
||||||
|
y = 0,
|
||||||
|
point = GridPoint:new( 0, 0 )
|
||||||
|
}
|
||||||
|
|
||||||
|
-- TODO: fix collision with other line's endpoint
|
||||||
|
function Mouse:update()
|
||||||
|
Mouse.x, Mouse.y = love.mouse.getPosition()
|
||||||
|
Mouse.x = Mouse.x + 1
|
||||||
|
Mouse.y = Mouse.y + 1
|
||||||
|
|
||||||
|
Mouse.point = GridPoint.snapCoords( Point:new( Mouse.x, Mouse.y ) )
|
||||||
|
end
|
||||||
42
point.lua
Normal file
42
point.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
-- Represents 2D point
|
||||||
|
---@class Point
|
||||||
|
Point = { x = 1, y = 1 }
|
||||||
|
|
||||||
|
-- Point factory
|
||||||
|
---@param x number | nil
|
||||||
|
---@param y number | nil
|
||||||
|
---@return any
|
||||||
|
function Point:new( x, y )
|
||||||
|
local point = {
|
||||||
|
x = x or x,
|
||||||
|
y = y or y
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable( point, { __index = self } )
|
||||||
|
|
||||||
|
return point
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Comparing function
|
||||||
|
---@param point self
|
||||||
|
---@return boolean
|
||||||
|
function Point:equals( point )
|
||||||
|
return self.x == point.x and self.y == point.y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get self coordinates
|
||||||
|
---@return number, number
|
||||||
|
function Point:coords()
|
||||||
|
return self.x, self.y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return vector length between points
|
||||||
|
---@param point Point
|
||||||
|
---@return number
|
||||||
|
function Point:distanceTo( point )
|
||||||
|
return math.sqrt(
|
||||||
|
( self.x - point.x ) ^ 2 +
|
||||||
|
( self.y - point.y ) ^ 2
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
71
port.lua
Normal file
71
port.lua
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
require 'gridpoint'
|
||||||
|
|
||||||
|
---@enum Alignment
|
||||||
|
Alignment = {
|
||||||
|
Vertical = true,
|
||||||
|
Horizontal = false
|
||||||
|
}
|
||||||
|
|
||||||
|
---@enum PortRotation
|
||||||
|
PortRotation = {
|
||||||
|
right = {false, false},
|
||||||
|
down = {false, true},
|
||||||
|
left = {true, false},
|
||||||
|
up = {true, true}
|
||||||
|
}
|
||||||
|
|
||||||
|
---@class Port
|
||||||
|
---@field position GridPoint
|
||||||
|
---@field alignment Alignment
|
||||||
|
---@field scanOffset number
|
||||||
|
---@field color table
|
||||||
|
Port = {
|
||||||
|
position = GridPoint:new(0, 0),
|
||||||
|
alignment = Alignment.Vertical,
|
||||||
|
scanOffset = 0,
|
||||||
|
color = { 0.8, 0.8, 0, 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param position GridPoint
|
||||||
|
---@param rotation PortRotation
|
||||||
|
---@param color table
|
||||||
|
---@return Port
|
||||||
|
function Port:new(position, rotation, color)
|
||||||
|
local port = {
|
||||||
|
position = position or self.position,
|
||||||
|
alignment = self.alignment,
|
||||||
|
scanOffset = self.scanOffset,
|
||||||
|
color = color or self.color
|
||||||
|
}
|
||||||
|
if rotation ~= nil then
|
||||||
|
port.scanOffset = rotation[1] and 1 or 0
|
||||||
|
port.alignment = rotation[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(port, { __index = self })
|
||||||
|
|
||||||
|
return port
|
||||||
|
end
|
||||||
|
|
||||||
|
function Port:rotateClockwise()
|
||||||
|
local swap = self.position.x
|
||||||
|
self.position.x = -self.position.y
|
||||||
|
self.position.y = swap
|
||||||
|
self.scanOffset = (self.scanOffset == 1) == self.alignment and 1 or 0
|
||||||
|
self.alignment = not self.alignment
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param offset GridPoint
|
||||||
|
function Port:draw( offset )
|
||||||
|
love.graphics.setColor(self.color)
|
||||||
|
local drawPoint = GridPoint:new(
|
||||||
|
offset.x + self.position.x + self.scanOffset,
|
||||||
|
offset.y + self.position.y + self.scanOffset
|
||||||
|
)
|
||||||
|
local x, y = drawPoint:globalCoords()
|
||||||
|
x = self.alignment and x - Config.cellSize / 2 or x - Config.portWidth / 2 - Config.cellSize / 2
|
||||||
|
y = self.alignment and y - Config.portWidth / 2 - Config.cellSize / 2 or y - Config.cellSize / 2
|
||||||
|
local w = self.alignment and Config.cellSize or Config.portWidth
|
||||||
|
local h = self.alignment and Config.portWidth or Config.cellSize
|
||||||
|
love.graphics.rectangle("fill", x, y, w, h)
|
||||||
|
end
|
||||||
27
tablefuncs.lua
Normal file
27
tablefuncs.lua
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
-- Find key by value in table by predicate
|
||||||
|
---@param table table
|
||||||
|
---@param value any
|
||||||
|
---@param pred function
|
||||||
|
---@return any
|
||||||
|
function TableFind( table, value, pred )
|
||||||
|
for key, innervalue in pairs( table ) do
|
||||||
|
if pred( value, innervalue ) then
|
||||||
|
return key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find if value exists in table by predicate
|
||||||
|
---@param table table
|
||||||
|
---@param value any
|
||||||
|
---@param pred function
|
||||||
|
---@return boolean
|
||||||
|
function TableHas( table, value, pred )
|
||||||
|
for _, innervalue in pairs( table ) do
|
||||||
|
if pred( value, innervalue ) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue