From 047c3ce7bed0f11e1f2bb5768d93e9be9c52ead2 Mon Sep 17 00:00:00 2001 From: Randy McShandy Date: Wed, 25 Feb 2026 21:24:17 -0600 Subject: [PATCH] NESFreeRoam camera finally working save some inter-map bugs --- main/assets.lua | 12 ++++++---- main/handlers.lua | 3 +-- main/main.lua | 6 ++--- main/render.lua | 49 +++++++++++++------------------------- main/tiled/side_scroll.lua | 10 ++++---- main/tiled/side_scroll.tmx | 10 ++++---- main/tiled/test_1.lua | 8 +++---- main/tiled/test_1.tmx | 4 ++-- 8 files changed, 44 insertions(+), 58 deletions(-) diff --git a/main/assets.lua b/main/assets.lua index 91cde40..14f6879 100644 --- a/main/assets.lua +++ b/main/assets.lua @@ -44,13 +44,17 @@ function assets.integrate_object_layers(pmap) -- of a map will override the first position an object is drawn in (and worse). for ok,ov in pairs(new_layer.objects) do local object = assets.get_object(ov.name) + + pmap[ov.name] = {} + pmap[ov.name].vec = vector.new_xy(ov.x, ov.y) + pmap[ov.name].name = ov.name + utils.shallow_dump('ovec', ov) + if object and utils.flag_set(object.properties, PropertyFlag.HasSprite) then object.image = love.graphics.newImage(object.path) + -- Tiled does y values from the bottom of the sprite so pull up 1 + pmap[ov.name].vec.y = ov.y - pmap.tileheight end - pmap[ov.name] = {} - -- Tiled does y values from the bottom of the sprite so pull up 1 - pmap[ov.name].vec = vector.new_xy(ov.x, ov.y - pmap.tileheight) - pmap[ov.name].name = ov.name end new_layer.draw = function(self) diff --git a/main/handlers.lua b/main/handlers.lua index 643dc3d..0af8f09 100644 --- a/main/handlers.lua +++ b/main/handlers.lua @@ -13,15 +13,14 @@ function love.handlers.map_changed(new_map_name) else print('invalid map: '..new_map_name) end - render.viewport = render.update_viewport() end -- Anything interested in a movement control should register its own handler here. function love.handlers.movement_control(key, value) player:movement_control(key, value) - render.map.topleft = render.map.active_camera(player) render.viewport = render.update_viewport() + render.map.active_map.topleft = render.map.active_camera(player) local n = math.random(1, assets.walk_sfx.size) love.audio.play(assets.walk_sfx[n]) diff --git a/main/main.lua b/main/main.lua index 47b15d2..4ac30d9 100644 --- a/main/main.lua +++ b/main/main.lua @@ -53,12 +53,10 @@ function love.draw() 'replace', 1) love.graphics.setStencilTest('greater', 0) - render.map.active_map:draw(render.map.topleft.x, render.map.topleft.y, render.map.scale) + render.map.active_map:draw(render.map.active_map.topleft.x, render.map.active_map.topleft.y, render.map.scale) last_color = { love.graphics.getColor() } love.graphics.setColor(render.color.dark) - local adjust = render.worldspace_to_viewspace(player.vec) - love.graphics.rectangle('line', adjust.x, adjust.y, tile.w, tile.h) - --love.graphics.print(IntroMessage, math.floor((conf.window.width/16) * 1), math.floor((conf.window.height/16) * 1)) + love.graphics.print(IntroMessage, math.floor((conf.window.width/16) * 1), math.floor((conf.window.height/16) * 1)) love.graphics.setColor(last_color) end diff --git a/main/render.lua b/main/render.lua index 3c79517..39c3131 100644 --- a/main/render.lua +++ b/main/render.lua @@ -4,7 +4,7 @@ assets = require('assets') conf = require('conf') utils = require('utils') -local render = {} +render = {} ViewClass = { @@ -29,7 +29,8 @@ render.color.light = { love.math.colorFromBytes(229, 229, 229) } -- Map rendering info render.map = {} -render.map.topleft = { x = 0, y = 0 } +render.map.active_map = {} +render.map.active_map.topleft = nil --{ x = 0, y = 0 } render.map.scale = 2.0 render.map.active_map = nil @@ -52,6 +53,7 @@ function render.activate_map(new_map_name) render.map.active_map = new_map render.map.scale = new_map.args.scale render.active_viewclass = render.ViewClassData[new_map.properties.viewclass] + render.viewport = render.update_viewport() -- Find all stored objects in the map we're switching to, and update their positional -- info with the unique copy stored in each map. @@ -60,8 +62,8 @@ function render.activate_map(new_map_name) if object_in_map then object.vec = object_in_map.vec if object_in_map.name == 'Player' then - render.map.active_map.first_loop = true - render.map.topleft = render.map.active_camera(object) + render.map.active_map.first_loop = (render.map.active_map.topleft == nil) + render.map.active_map.topleft = render.map.active_camera(object) end end end @@ -96,26 +98,6 @@ function render.update_viewport() return new_viewport end --- Convert an absolute position in the map/gameworld --- to where it would show up in the viewport. -function render.worldspace_to_viewspace(world_position) - local view_position = utils.shallow_copy(world_position) - local tile = { - w = render.map.active_map.tilewidth , - h = render.map.active_map.tileheight, - } - - local offsets = - { - x = (render.viewport.ex * math.floor((render.map.scale * world_position.x) / render.viewport.ex)), - y = (render.viewport.ey * math.floor((render.map.scale * world_position.y) / render.viewport.ey)), - } - view_position.x = (render.map.scale * world_position.x) + (render.viewport.ox) - offsets.x - view_position.y = (render.map.scale * world_position.y) + (render.viewport.oy) - offsets.y - - return view_position -end - render.CameraClass = { -- Constantly place the player in the dead center of the window PlayerInMiddle = 1, @@ -152,27 +134,30 @@ function(focus) h = render.map.active_map.tileheight * render.map.scale, } + local cf = utils.shallow_copy(render.map.active_map['CameraFocus'].vec) + cf.x = cf.x * render.map.scale + cf.y = cf.y * render.map.scale + -- On the first focusing of a map in this mode, find the map's CameraFocus object -- and use that for our topleft if render.map.active_map.first_loop then render.map.active_map.first_loop = false return { - x = render.map.active_map['CameraFocus'].vec.x + (tile.w / 2), - y = render.map.active_map['CameraFocus'].vec.y + (tile.h), + x = -render.map.active_map['CameraFocus'].vec.x + (tile.w / render.map.scale), + y = -render.map.active_map['CameraFocus'].vec.y + (tile.h / render.map.scale), } end - local new_topleft = render.map.topleft - local viewspace_focus = render.worldspace_to_viewspace(focus.vec) + local new_topleft = utils.shallow_copy(render.map.active_map.topleft) - if ((focus.vec.heading == utils.Headings.East) and viewspace_focus.x <= render.viewport.ox) then + if ((focus.vec.heading == utils.Headings.East) and (((focus.vec.x * render.map.scale) - cf.x) % render.viewport.ex) == 0) then new_topleft.x = new_topleft.x - (render.viewport.ex / render.map.scale) - elseif ((focus.vec.heading == utils.Headings.West) and viewspace_focus.x >= render.viewport.ex) then + elseif ((focus.vec.heading == utils.Headings.West) and (((focus.vec.x * render.map.scale) - cf.x) % render.viewport.ex) == (render.viewport.ex - tile.w)) then new_topleft.x = new_topleft.x + (render.viewport.ex / render.map.scale) - elseif ((focus.vec.heading == utils.Headings.South) and viewspace_focus.y <= render.viewport.oy) then + elseif ((focus.vec.heading == utils.Headings.South) and (((focus.vec.y * render.map.scale) - cf.y) % render.viewport.ey) == 0) then new_topleft.y = new_topleft.y - (render.viewport.ey / render.map.scale) - elseif ((focus.vec.heading == utils.Headings.North) and viewspace_focus.y >= render.viewport.ey) then + elseif ((focus.vec.heading == utils.Headings.North) and (((focus.vec.y * render.map.scale) - cf.y) % render.viewport.ey) == (render.viewport.ey - tile.h)) then new_topleft.y = new_topleft.y + (render.viewport.ey / render.map.scale) end return new_topleft diff --git a/main/tiled/side_scroll.lua b/main/tiled/side_scroll.lua index f8c89a3..063ae60 100644 --- a/main/tiled/side_scroll.lua +++ b/main/tiled/side_scroll.lua @@ -108,11 +108,11 @@ return { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + 873, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 872, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 871, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 870, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 869, 870, 871, 872, 873, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }, { diff --git a/main/tiled/side_scroll.tmx b/main/tiled/side_scroll.tmx index d1f2c25..2fb1861 100644 --- a/main/tiled/side_scroll.tmx +++ b/main/tiled/side_scroll.tmx @@ -29,11 +29,11 @@ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, -1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +873,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +872,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +871,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +870,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +869,870,871,872,873,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 diff --git a/main/tiled/test_1.lua b/main/tiled/test_1.lua index 39600e8..be6d3cc 100644 --- a/main/tiled/test_1.lua +++ b/main/tiled/test_1.lua @@ -236,8 +236,8 @@ return { name = "Player", type = "", shape = "rectangle", - x = 16, - y = 32, + x = 80, + y = 160, width = 16, height = 16, rotation = 0, @@ -250,8 +250,8 @@ return { name = "CameraFocus", type = "Meta", shape = "point", - x = 0, - y = 0, + x = 32, + y = 48, width = 0, height = 0, rotation = 0, diff --git a/main/tiled/test_1.tmx b/main/tiled/test_1.tmx index 31cc2ae..de6deaa 100644 --- a/main/tiled/test_1.tmx +++ b/main/tiled/test_1.tmx @@ -133,8 +133,8 @@ - - + + -- 2.49.0