From 9635e0ea2f071c88be872ca6ab4d8083b9dd730c Mon Sep 17 00:00:00 2001 From: wan-may Date: Wed, 1 May 2024 21:32:07 -0300 Subject: [PATCH] Fixed the travel node loading bugs! --- button.lua | 6 ++--- camera.lua | 12 +++++++--- lines.lua | 14 +++++++++++ main.lua | 14 +++++++---- mainmenu.lua | 3 +-- map.lua | 21 +++++++++-------- savemodal.lua | 8 +++---- territory.lua | 1 + travelNodes.lua | 62 ++++++++++++++++++++++++++++++++++++++++++------- 9 files changed, 106 insertions(+), 35 deletions(-) diff --git a/button.lua b/button.lua index 603ff2d..12dc0ba 100644 --- a/button.lua +++ b/button.lua @@ -59,9 +59,9 @@ function t.draw( b ) elseif b.visible then lg.rectangle( "line", b.x, b.y, b.w, b.h, 6 ) lg.printf( b.name, - b.x, - b.y + 0.5 * ( b.h- lg.getFont():getHeight() ), - b.w, + b.x + (b.icon and b.h or 0), + b.y + 0.5 * ( b.h - lg.getFont():getHeight() ), + b.w - (b.icon and b.h or 0), "center" ) if b.icon then local h = b.icon:getHeight() diff --git a/camera.lua b/camera.lua index 3c5c8b4..0fc42fd 100644 --- a/camera.lua +++ b/camera.lua @@ -21,10 +21,16 @@ function Camera.GetNodeCoordinate( x, y ) end function Camera.Zoom( delta ) - local scale = 1.0 + delta if Camera.zoom < 25.0 and delta > 0 or --zooming in Camera.zoom > 0.5 and delta < 0 then --zooming out - return Camera.Set( Camera.x , Camera.y, Camera.w * scale, Camera.h * scale ) + + delta = delta * Camera.zoom + local cx, cy = Camera.x, Camera.y + return Camera.Set( + cx, + cy, + Camera.w + delta, + Camera.h * (Camera.w + delta) / Camera.w ) end end @@ -34,7 +40,7 @@ function Camera.Translate( x, y ) return Camera.Set( math.max(-180, math.min(360, Camera.x + x)), math.min(100, Camera.y + y), Camera.w, Camera.h) end ---In world coordinates: top left corner at x, y, extent of w, h. +--In world coordinates: top left corner at x, y, extent of 1/w, 1/h. function Camera.Set( x, y, w, h ) Camera.x, Camera.y, Camera.w, Camera.h = x, y, w, h Camera.zoom = w / 800 diff --git a/lines.lua b/lines.lua index 2b67877..1eddb14 100644 --- a/lines.lua +++ b/lines.lua @@ -15,6 +15,20 @@ function polygon:formatDisplayInfo() N: %d]]):format( self.x, self.y, self.X, self.Y, #self ) end +function polygon:drawDirection() + local a,b,c,d = self[1], self[2], self[3], self[4] + + local bx, by = (c + a) / 2, (b + d) / 2 + local dx, dy = c - a, d - b + local r = math.max( math.sqrt( dy * dy + dx * dx ), 0.0001 ) + dx, dy = dx / r, dy / r + lg.polygon( "fill", + a + dx, b + dy, + a - 0.4 * dy, b + 0.4 * dx, + a + 0.4 * dy, b - 0.4 * dx ) + +end + function t.load( filename ) local polys = { visible = true, filename = filename } local poly = {} diff --git a/main.lua b/main.lua index 6a58c70..2e83b2e 100644 --- a/main.lua +++ b/main.lua @@ -27,8 +27,8 @@ function love.update( dt ) if love.keyboard.isScancodeDown( "a" ) then moveCamera = true; tx = tx - 30 * dt end if love.keyboard.isScancodeDown( "s" ) then moveCamera = true; ty = ty - 30 * dt end if love.keyboard.isScancodeDown( "d" ) then moveCamera = true; tx = tx + 30 * dt end - if love.keyboard.isScancodeDown( "q" ) then Camera.Zoom( dt ) end - if love.keyboard.isScancodeDown( "e" ) then Camera.Zoom( -dt ) end + if love.keyboard.isScancodeDown( "q" ) then Camera.Zoom( dt * 400 ) end + if love.keyboard.isScancodeDown( "e" ) then Camera.Zoom( -dt* 400 ) end if moveCamera then Camera.Translate( tx, ty ) end @@ -49,7 +49,7 @@ function love.draw() local wx, wy = Camera.GetWorldCoordinate( x, y ) local bx, by = Camera.GetBitmapCoordinate( x, y ) local h = love.graphics.getHeight() - 60 - love.graphics.setColor( 0.1, 0.1, 0.5, 0.8 ) + love.graphics.setColor( 0, 0, 0, 0.9 ) love.graphics.rectangle( "fill", 0, 0, 250, love.graphics.getHeight() ) love.graphics.setColor( 1, 1, 1, 1 ) love.graphics.print(([[ @@ -61,7 +61,11 @@ function love.draw() if map.selected then love.graphics.print( map.selected:formatDisplayInfo(), 0, 80 ) end if map.selectionLocked then end - love.graphics.setColor( 1, 1, 1, 0.8 ) + + love.graphics.rectangle( "line", 0, 0 , 250, 218 ) + love.graphics.rectangle( "line", 0, 218, 250, love.graphics.getHeight() ) + + love.graphics.setColor( 1, 1, 1, 0.6 ) button:draw() end @@ -70,7 +74,7 @@ function love.resize(w, h) end function love.wheelmoved(x, y) - Camera.Zoom( (y > 0) and 0.1 or -0.1 ) + Camera.Zoom( (y > 0) and 3 or -3 ) end function love.mousepressed( x, y, mouseButton, istouch, presses ) diff --git a/mainmenu.lua b/mainmenu.lua index 2c62e6e..98ff029 100644 --- a/mainmenu.lua +++ b/mainmenu.lua @@ -16,7 +16,7 @@ local function back( self ) map.editLayer = false end -backButton = button.new{ +local backButton = button.new{ name = "UP", visible = false, y = 250 + button.h + 4, @@ -84,7 +84,6 @@ local function soloVisibleLayer( self ) return updateVisibilityIcons() end -local backButton local function editLayer( self ) map.editLayer = map.layers[ self.layer ] map.editLayer.visible = true diff --git a/map.lua b/map.lua index c2801a7..155a82c 100644 --- a/map.lua +++ b/map.lua @@ -51,16 +51,16 @@ local map = { } function map.load( path ) - map.background = lg.newImage( "data/graphics/blur.bmp" ) - map.cities = Cities.load( "data/earth/cities.dat" ) - map.coastlines = Lines.load( "data/earth/coastlines.dat" ) - map.coastlinesLow = Lines.load( "data/earth/coastlines-low.dat" ) - map.international = Lines.load( "data/earth/international.dat" ) - map.sailable = Territory.load( "data/earth/sailable.bmp", "sailable" ) - map.travelnodes = Nodes.load( "data/earth/travel_nodes.bmp", map.sailable.isSailable ) --travel node adjacency matrix depends on sailable bitmap - map.ainodes = AI.load( "data/earth/ai_markers.bmp" ) + map.background = lg.newImage( "/data/graphics/blur.bmp" ) + map.cities = Cities.load( "/data/earth/cities.dat" ) + map.coastlines = Lines.load( "/data/earth/coastlines.dat" ) + map.coastlinesLow = Lines.load( "/data/earth/coastlines-low.dat" ) + map.international = Lines.load( "/data/earth/international.dat" ) + map.sailable = Territory.load( "/data/earth/sailable.bmp", "sailable" ) + map.travelnodes = Nodes.load( "/data/earth/travel_nodes.bmp", map.sailable.isSailable ) --travel node adjacency matrix depends on sailable bitmap + map.ainodes = AI.load( "/data/earth/ai_markers.bmp" ) for k, v in pairs(map.territory) do - map.territory[k] = Territory.load( "data/earth/"..k..".bmp", k ) + map.territory[k] = Territory.load( "/data/earth/"..k..".bmp", k ) end map.loaded = true map.path = path @@ -119,8 +119,9 @@ function map.draw() lg.setColor( 0.4, 0.5, 0.8, 0.5 ) lg.setLineWidth( 0.2 / Camera.zoom ) lg.rectangle( "fill", p.x, p.y, p.X - p.x, p.Y - p.y ) - lg.setColor( 1.0, 0, 0, 1 ) + lg.setColor( 1.0, 0, 0, 0.5 ) lg.line( p ) + p:drawDirection() else --points lg.setColor( 1.0, 0.5, 0.5, 0.9 ) lg.setLineJoin( "miter" ) diff --git a/savemodal.lua b/savemodal.lua index af01e9b..fbf30c1 100644 --- a/savemodal.lua +++ b/savemodal.lua @@ -13,9 +13,9 @@ local saveButton = button.new{ callback = function() map.save(); return t:stop() end, visible = false, icon = floppy, - x = love.graphics.getWidth() / 2 - 200, + x = love.graphics.getWidth() / 2 - 300, y = love.graphics.getHeight() / 2 - 150, - w = 400, + w = 600, h = 100, } @@ -27,9 +27,9 @@ local cancelButton = button.new{ visible = false, icon = xIcon, callback = function() return t:stop() end, - x = love.graphics.getWidth() / 2 - 200, + x = love.graphics.getWidth() / 2 - 300, y = love.graphics.getHeight() / 2, - w = 400, + w = 600, h = 100 } diff --git a/territory.lua b/territory.lua index 4209102..55765c9 100644 --- a/territory.lua +++ b/territory.lua @@ -111,6 +111,7 @@ function t.computeBorder( territory, threshold, key ) local n = 1 local w, h = territory.imgd:getWidth() - 1, territory.imgd:getHeight() - 1 + w, h = math.min( 512, w ), math.min( 285, h ) for x = 0, w do for y = 0, h do --Bottom left, bottom right, and top right of pixel in image coordinates: diff --git a/travelNodes.lua b/travelNodes.lua index b554d3c..59a01d5 100644 --- a/travelNodes.lua +++ b/travelNodes.lua @@ -10,17 +10,18 @@ local lg = assert( love.graphics ) local t = setmetatable({}, {__index = locationQuery}) local isSailable -local function isConnected( startNode, endNode ) +local function hasEdge( startNode, endNode ) local ix, iy, fx, fy = startNode.x, startNode.y, endNode.x, endNode.y if fx < -180 then fx = fx + 180 end if fx > 180 then fx = fx - 180 end local dx, dy = fx - ix, fy - iy local mag = math.sqrt( dx * dx + dy * dy ) - local n = 2 * math.floor( mag ) - dx, dy = 0.5 * dx / mag, 0.5 * dy / mag + local n = math.floor( mag )--/ 0.5 ) + dx, dy = dx / mag, dy / mag + --dx, dy = 0.5 * dx, 0.5 * dy - for i = 1, n do + for i = 0, n - 1 do ix, iy = ix + dx, iy + dy if not( isSailable( ix, -iy ) ) then return nil end end @@ -46,8 +47,12 @@ local function worldToBitmap( x, y ) end local function bitmapToWorld( x, y ) - return 360 * ( x - 800 ) / 800 - 360 / 2 + 360, - 360 * ( 600 / 800 ) * ( y - 600 ) / 600 + 180 + local w, a = 360.0, 600.0 / 800.0 + local h = 360.0 * a + x = w * ( x - 800 ) / 800 - w / 2 + 360 + y = h * ( y - 600 ) / 600 + 180 + return x, y + --(360 * ( 600 / 800 )) * ( y - 600 ) / 600 + 180 end function t.load( filename, sailable ) @@ -55,6 +60,7 @@ function t.load( filename, sailable ) isSailable = sailable local img, imgd = bmp.load( filename ) local nodes = { filename = filename, visible = true, nodes = {}, points = {}, connections = {}, img = img } + t.nodes = nodes local n = 1 for x = 0, 799 do for y = 0, 399 do @@ -72,31 +78,71 @@ function t.load( filename, sailable ) local adjacent = {} for j, destNode in ipairs( nodes.nodes ) do - adjacent[j] = isConnected( srcNode, destNode ) + adjacent[j] = hasEdge( srcNode, destNode ) end nodes.connections[i] = adjacent end + + for i, node in ipairs( nodes.nodes ) do + for j, destNode in ipairs( nodes.nodes ) do + nodes.connections[i][j] = nodes.connections[i][j] or nodes.connections[j][i] + end + end + + nodes.connected = t.isConnected( nodes ) nodes.nodes = locationQuery.New( nodes.nodes ) setmetatable( nodes, {__index = t} ) return nodes end +local function updateAdjacency( connections, i ) + for j in pairs( connections[i] ) do + local edge = hasEdge( i, j ) + connections[j][i] = edge + connections[i][j] = edge + end +end + +local function dfs( idx, adj, unvisited ) + if not unvisited[idx] then return end + print( "visiting node", idx ) + unvisited[ idx ] = nil + for i in pairs( adj[idx] ) do dfs( i, adj, unvisited ) end +end + --Determine if graph has more than one connected component. function t.isConnected( nodes ) + local adj = nodes.connections + local unvisited = {} + for i in ipairs( nodes.nodes ) do + unvisited[i] = true + end + print( "DEPTH FIRST SEARCH:", "total nodes", #unvisited) + dfs( 1, adj, unvisited ) + for k in pairs( unvisited ) do + print( "DEPTH FIRST SEARCH:", "unvisited", k) + end + return not(next(unvisited)) --empty if a graph is connected end function t.draw( nodes ) lg.setPointSize( 8 ) - lg.setColor( 1, 1, 1, 0.5 ) + lg.setColor( 1, 1, 1, 0.7 ) lg.points( nodes.points ) return t.drawConnections( nodes ) end function t.drawConnections( nodes ) + if nodes.connected then + lg.setColor( 1, 1, 1, 0.4 ) + else + lg.setColor( 1, 0, 0, 0.7 ) + end + for i, connection in pairs( nodes.connections ) do for j in pairs( connection ) do local ix, iy, fx, fy = nodes.nodes[i].x, nodes.nodes[i].y, nodes.nodes[j].x, nodes.nodes[j].y