From: Randy McShandy Date: Sun, 22 Feb 2026 14:56:00 +0000 (-0600) Subject: Looks like NES-style map movement works X-Git-Url: http://git.mcshandy.xyz/gitweb.cgi?a=commitdiff_plain;h=93d2e2328f5cd7f4b29a4e7a7aa3483d70248dfb;p=sumeriangame Looks like NES-style map movement works --- diff --git a/main/assets.lua b/main/assets.lua index 4351fdd..1a05094 100644 --- a/main/assets.lua +++ b/main/assets.lua @@ -24,7 +24,9 @@ PropertyFlag = Active = 1, -- Will be moving around or need other periodic updates -- and should provide its own update function Controllable = 2, -- Can be controlled in some way + HasSprite = 3, } +assets.PropertyFlag = PropertyFlag function assets.integrate_object_layers(pmap) for k,layer in pairs(pmap.layers) do @@ -42,13 +44,13 @@ 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) - if object then + if object and utils.flag_set(object.properties, PropertyFlag.HasSprite) then object.image = love.graphics.newImage(object.path) - 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 + 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) @@ -138,9 +140,10 @@ assets.walk_sfx.size = 3 -- If relevant, an Object asset's name should match an object as placed -- in an Object layer of a Tiled map assets.store_object('Player', { - properties = (PropertyFlag.Active), + properties = bit.bor(PropertyFlag.Active, PropertyFlag.Controllable, PropertyFlag.HasSprite), path = 'assets/sprites/gilgamesh.png', vec = vector.new_xy(), + viewspace = vector.new_xy(), update = function(self, dt) end }) diff --git a/main/control.lua b/main/control.lua index f4007f4..cddcb13 100644 --- a/main/control.lua +++ b/main/control.lua @@ -17,19 +17,19 @@ control.keymap.active_keymap = nil control.keymap[render.ViewClass.Topdown] = {} control.keymap[render.ViewClass.Sidescroll] = {} -control.keymap[render.ViewClass.Topdown]['l'] = { heading = (math.pi / 2) * -0, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['k'] = { heading = (math.pi / 2) * -1, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['h'] = { heading = (math.pi / 2) * -2, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['j'] = { heading = (math.pi / 2) * -3, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['d'] = { heading = (math.pi / 2) * -0, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['w'] = { heading = (math.pi / 2) * -1, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['a'] = { heading = (math.pi / 2) * -2, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Topdown]['s'] = { heading = (math.pi / 2) * -3, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['l'] = { heading = utils.Headings.East, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['k'] = { heading = utils.Headings.North, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['h'] = { heading = utils.Headings.West, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['j'] = { heading = utils.Headings.South, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['d'] = { heading = utils.Headings.East, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['w'] = { heading = utils.Headings.North, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['a'] = { heading = utils.Headings.West, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Topdown]['s'] = { heading = utils.Headings.South, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Sidescroll]['l'] = { heading = (math.pi / 2) * -0, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Sidescroll]['h'] = { heading = (math.pi / 2) * -2, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Sidescroll]['a'] = { heading = (math.pi / 2) * -2, control = control.ControlType.Movement, } -control.keymap[render.ViewClass.Sidescroll]['d'] = { heading = (math.pi / 2) * -0, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Sidescroll]['l'] = { heading = utils.Headings.East, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Sidescroll]['h'] = { heading = utils.Headings.West, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Sidescroll]['a'] = { heading = utils.Headings.West, control = control.ControlType.Movement, } +control.keymap[render.ViewClass.Sidescroll]['d'] = { heading = utils.Headings.East, control = control.ControlType.Movement, } control.keymap['global'] = {} control.keymap['global']['q'] = { diff --git a/main/main.lua b/main/main.lua index 53edad8..d32100e 100644 --- a/main/main.lua +++ b/main/main.lua @@ -52,6 +52,8 @@ function love.draw() last_color = { love.graphics.getColor() } love.graphics.setColor(render.color.dark) - love.graphics.print(IntroMessage, math.floor((conf.window.width/16) * 1), math.floor((conf.window.height/16) * 1)) + local adjust = render.worldspace_to_viewspace(player.vec) + love.graphics.rectangle('line', adjust.x, adjust.y, 32, 32) + --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/player.lua b/main/player.lua index d0c0370..c1d2b7a 100644 --- a/main/player.lua +++ b/main/player.lua @@ -20,6 +20,8 @@ function player_module.init_controls(player_obj, active_map) -- Direction vectors for each heading local dx = math.floor(math.cos(value.heading) + 0.5) local dy = math.floor(math.sin(value.heading) + 0.5) + -- Update the player's heading for use elsewhere + player_obj.vec.heading = value.heading local target_tile_x = current_tile_x + dx local target_tile_y = current_tile_y + dy diff --git a/main/render.lua b/main/render.lua index fd03337..db59089 100644 --- a/main/render.lua +++ b/main/render.lua @@ -34,9 +34,7 @@ render.map.scale = 2.0 render.map.active_map = nil -- A bounding box to mask rendering for the main scene. --- e.g., anything outside this (or in?) should not be rendered. --- I don't know if Love supports this but I can always just draw black boxes lol. --- Look into love.graphics.stencil +-- e.g., anything outside this should not be rendered. render.viewport = { ox = 0, @@ -45,14 +43,14 @@ render.viewport = ey = conf.window.height, } -render.activate_map = function(new_map_name) +function render.activate_map(new_map_name) local success = false - local new_map = assets.get_map(new_map_name) if new_map then success = true render.map.active_map = new_map render.active_viewclass = render.ViewClassData[new_map.properties.viewclass] + render.map.active_map.first_loop = true -- Find all objects in the map we're switching to, and update their positional -- info with the unique copy stored in each map. @@ -62,6 +60,8 @@ render.activate_map = function(new_map_name) object.vec = object_in_map.vec if key == 'Player' then render.map.topleft = render.map.active_camera(object) + elseif key == 'CameraFocus' then + render.map.topleft = render.map.active_camera(object) end end end @@ -98,6 +98,26 @@ 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, @@ -109,25 +129,57 @@ render.CameraClass = { render.map.cameras = {} render.map.cameras[render.CameraClass.PlayerInMiddle] = function(focus, bounds) + if render.map.active_map.first_loop then + render.map.active_map.first_loop = false + end + local offsets = {} - local new_txty = + local new_topleft = { x = (((conf.window.width / 2) / render.map.scale) - (focus.vec.x)), y = (((conf.window.height / 2) / render.map.scale) - (focus.vec.y)), } - offsets.x = math.fmod(new_txty.x, (render.map.active_map.tilewidth)) - offsets.y = math.fmod(new_txty.y, (render.map.active_map.tileheight)) - new_txty.x = new_txty.x - offsets.x - new_txty.y = new_txty.y - offsets.y - return new_txty + offsets.x = math.fmod(new_topleft.x, (render.map.active_map.tilewidth)) + offsets.y = math.fmod(new_topleft.y, (render.map.active_map.tileheight)) + new_topleft.x = new_topleft.x - offsets.x + new_topleft.y = new_topleft.y - offsets.y + + return new_topleft end render.map.cameras[render.CameraClass.NESFreeRoam] = function(focus) - -- temp code - return focus.vec or { x = 0, y = 0 } + local tile = { + w = render.map.active_map.tilewidth * render.map.scale, + h = render.map.active_map.tileheight * 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), + } + end + + local new_topleft = render.map.topleft + local viewspace_focus = render.worldspace_to_viewspace(focus.vec) + + if ((focus.vec.heading == utils.Headings.East) and viewspace_focus.x == render.viewport.ox) 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 + 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 + 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 + new_topleft.y = new_topleft.y + (render.viewport.ey / render.map.scale) + end + return new_topleft end -render.map.active_camera = render.map.cameras[render.CameraClass.PlayerInMiddle] +render.map.active_camera = render.map.cameras[render.CameraClass.NESFreeRoam] return render diff --git a/main/tiled/test_1.lua b/main/tiled/test_1.lua index 3e6823c..ff8c73f 100644 --- a/main/tiled/test_1.lua +++ b/main/tiled/test_1.lua @@ -10,7 +10,7 @@ return { tilewidth = 16, tileheight = 16, nextlayerid = 7, - nextobjectid = 13, + nextobjectid = 14, properties = { ["viewclass"] = "topdown" }, @@ -198,9 +198,9 @@ return { 51, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 746, 747, 748, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 922, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 746, 747, 748, 0, 0, 0, 0, 0, 0, 0, 0, 1, 923, 0, 0, 0, 0, 0, 0, 206, 2684354765, 1610612941, 2684354765, 1610612941, 2684354765, 2684354766, 0, 0, 0, 0, 795, 796, 797, 0, 0, 0, 0, 0, 0, 0, 0, 51, 924, 0, 0, 0, 0, 0, 0, 3221225677, 0, 0, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 925, 0, 0, 0, 0, 0, 0, 205, 206, 1610612941, 2684354765, 1610612941, 2684354766, 3221225677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, @@ -244,6 +244,19 @@ return { gid = 515, visible = true, properties = {} + }, + { + id = 13, + name = "CameraFocus", + type = "Meta", + shape = "point", + x = 0, + y = 0, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} } } } diff --git a/main/tiled/test_1.tmx b/main/tiled/test_1.tmx index 3c96aa4..28c2e29 100644 --- a/main/tiled/test_1.tmx +++ b/main/tiled/test_1.tmx @@ -1,5 +1,5 @@ - + @@ -113,9 +113,9 @@ 51,869,870,871,872,873,874,875,876,877,878,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, 918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, 919,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, -920,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, -921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, -922,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,746,747,748,0,0,0,0,0,0,0,0,51, +920,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +922,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,746,747,748,0,0,0,0,0,0,0,0,1, 923,0,0,0,0,0,0,206,2684354765,1610612941,2684354765,1610612941,2684354765,2684354766,0,0,0,0,795,796,797,0,0,0,0,0,0,0,0,51, 924,0,0,0,0,0,0,3221225677,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, 925,0,0,0,0,0,0,205,206,1610612941,2684354765,1610612941,2684354766,3221225677,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51, @@ -134,5 +134,8 @@ + + + diff --git a/main/utils.lua b/main/utils.lua index 1137b20..7b18e40 100644 --- a/main/utils.lua +++ b/main/utils.lua @@ -3,10 +3,22 @@ local bit = require('bit') local utils = {} +utils.Headings = +{ + East = math.pi / 2 * -0, + North = math.pi / 2 * -1, + West = math.pi / 2 * -2, + South = math.pi / 2 * -3, +} + function utils.flag_set(value, flag) return (bit.band(value, flag) ~= 0) end +function utils.set_flag(value, flag) + return (bit.bor(value, flag)) +end + function utils.shallow_copy(t) local t2 = {} for k,v in pairs(t) do @@ -15,12 +27,22 @@ function utils.shallow_copy(t) return t2 end -function utils.shallow_dump(t) - if t then - for k,v in pairs(t) do - print(k..':', v) +function utils.shallow_dump(delim, ...) + for vark,varv in pairs({...}) do + print(delim..vark..':') + for k,v in pairs(varv) do + print('\t'..k..':', v) end end end +function utils.outside_box(box, pos) + -- return a vector indicating which way pos went out of the box + return + { + x = (pos.x >= (box.ex) and 1 or (pos.x < (box.ox - 32) and -1 or 0)), + y = (pos.y >= (box.ey) and 1 or (pos.y < box.oy and -1 or 0)), + } +end + return utils