diff --git a/level_editor/editor.lua b/level_editor/editor.lua index 524b9a5..a11fe29 100644 --- a/level_editor/editor.lua +++ b/level_editor/editor.lua @@ -44,6 +44,57 @@ local assetSearchText = "" local assetSearchButtons = {} local worldSearchText = "" local worldSearchBox = { x = 10, y = 34, w = 0, h = 28 } +local roomBrush = nil + +-- Convert a pointer position into a valid room cell. Keeping brush state in +-- cell coordinates means a click that jitters within a tile cannot place or +-- erase that tile more than once. +local function roomCellAt(x, y) + if x < 0 or x >= width or y < 0 or y >= height then return nil end + local cell = currentRoom:getCellFromMousePos(x, y) + cell.x = constrain(cell.x, 1, gridWidth) + cell.y = constrain(cell.y, 1, gridHeight) + return cell +end + +local function paintRoomCell(cell, button) + -- Use the centre of the cell so Room's existing pointer-based edit helpers + -- perform the same operation as a normal click. + local x = (cell.x - .5) * width / gridWidth + local y = (cell.y - .5) * height / gridHeight + if button == 1 and selectedAsset then + currentRoom:attemptPlace(selectedAsset, gameAssets[selectedAsset], x, y, selectedColor) + elseif button == 2 then + currentRoom:attemptDelete(x, y, selectedColor) + end +end + +local function paintRoomLine(from, to, button) + -- Bresenham keeps a fast mouse movement from leaving holes between the + -- cells that happened to receive mouse-move events. + local x, y = from.x, from.y + local dx, dy = math.abs(to.x - x), math.abs(to.y - y) + local stepX = x < to.x and 1 or -1 + local stepY = y < to.y and 1 or -1 + local err = dx - dy + + while true do + if x ~= from.x or y ~= from.y then paintRoomCell({ x = x, y = y }, button) end + if x == to.x and y == to.y then break end + local twiceErr = err * 2 + if twiceErr > -dy then err = err - dy; x = x + stepX end + if twiceErr < dx then err = err + dx; y = y + stepY end + end +end + +local function beginRoomBrush(x, y, button) + if button ~= 1 and button ~= 2 then return end + if button == 1 and not selectedAsset then return end + local cell = roomCellAt(x, y) + if not cell then return end + paintRoomCell(cell, button) + roomBrush = { button = button, lastCell = cell } +end -- ── Room-view sidebar layout ──────────────────────────────────────────────── -- Declared up here (not next to editorDraw) so editorMouseHandler, defined @@ -730,8 +781,8 @@ function editorMouseHandler(x, y, button) end else -- click landed on the grid (game area): place the selected asset - if editorView == "room" and button == 1 and selectedAsset then - currentRoom:attemptPlace(selectedAsset, gameAssets[selectedAsset], x, y, selectedColor) + if editorView == "room" then + beginRoomBrush(x, y, button) elseif editorView == "world" then local cellX, cellY = gameWorld:getCellFromMousePos(x, y) if not gameWorld:isInBounds(cellX, cellY) then return end @@ -748,6 +799,30 @@ function editorMouseHandler(x, y, button) end end +function editorMouseMoved(x, y) + if not roomBrush then return end + if editorView ~= "room" then + roomBrush = nil + return + end + + local cell = roomCellAt(x, y) + if not cell then + -- Leaving the grid ends this stroke; re-entering should not draw a line + -- across the sidebar or outside of the level. + roomBrush = nil + return + end + if cell.x == roomBrush.lastCell.x and cell.y == roomBrush.lastCell.y then return end + + paintRoomLine(roomBrush.lastCell, cell, roomBrush.button) + roomBrush.lastCell = cell +end + +function editorMouseReleased(_, _, button) + if roomBrush and roomBrush.button == button then roomBrush = nil end +end + function editorTextHandler(text) if editorView == "asset" and activeField then inputText = text @@ -809,6 +884,11 @@ function editorDraw() item.x, item.y = s.list.pos(i) item.w = s.listRect.w item:draw() + if item.name == "asset" and item.text == selectedAsset then + love.graphics.setColor(1, 0.85, 0.2, 1) + love.graphics.setLineWidth(3) + love.graphics.rectangle("line", item.x + 1, item.y + 1, item.w - 2, item.h - 2) + end end end Layout.unclip() diff --git a/main.lua b/main.lua index e80f763..c1dc6f9 100644 --- a/main.lua +++ b/main.lua @@ -190,12 +190,17 @@ function love.keypressed(key) end function love.mousepressed(x, y, button) - if editorView == "room" and button == 2 then - currentRoom:attemptDelete(x, y, selectedColor) - end editorMouseHandler(x, y, button) end +function love.mousemoved(x, y) + editorMouseMoved(x, y) +end + +function love.mousereleased(x, y, button) + editorMouseReleased(x, y, button) +end + function love.textinput(t) response = response .. t editorTextHandler(response) diff --git a/rooms/ok.sav b/rooms/ok.sav new file mode 100644 index 0000000..2ab39e4 --- /dev/null +++ b/rooms/ok.sav @@ -0,0 +1,760 @@ +{ +objects={ + { + x=11, + y=11, + class="static_wall", + color="green" + }, + { + x=11, + y=10, + class="static_wall", + color="green" + }, + { + x=11, + y=9, + class="static_wall", + color="green" + }, + { + x=11, + y=8, + class="static_wall", + color="green" + }, + { + x=11, + y=7, + class="static_wall", + color="green" + }, + { + x=11, + y=6, + class="static_wall", + color="green" + }, + { + x=11, + y=4, + class="static_wall", + color="green" + }, + { + x=11, + y=3, + class="static_wall", + color="green" + }, + { + x=11, + y=2, + class="static_wall", + color="green" + }, + { + x=11, + y=1, + class="static_wall", + color="green" + }, + { + x=10, + y=1, + class="static_wall", + color="green" + }, + { + x=9, + y=1, + class="static_wall", + color="green" + }, + { + x=8, + y=1, + class="static_wall", + color="green" + }, + { + x=7, + y=1, + class="static_wall", + color="green" + }, + { + x=6, + y=1, + class="static_wall", + color="green" + }, + { + x=5, + y=1, + class="static_wall", + color="green" + }, + { + x=4, + y=1, + class="static_wall", + color="green" + }, + { + x=3, + y=1, + class="static_wall", + color="green" + }, + { + x=2, + y=1, + class="static_wall", + color="green" + }, + { + x=1, + y=1, + class="static_wall", + color="green" + }, + { + x=1, + y=2, + class="static_wall", + color="green" + }, + { + x=1, + y=3, + class="static_wall", + color="green" + }, + { + x=1, + y=4, + class="static_wall", + color="green" + }, + { + x=1, + y=5, + class="static_wall", + color="green" + }, + { + x=1, + y=6, + class="static_wall", + color="green" + }, + { + x=1, + y=7, + class="static_wall", + color="green" + }, + { + x=1, + y=8, + class="static_wall", + color="green" + }, + { + x=1, + y=9, + class="static_wall", + color="green" + }, + { + x=1, + y=10, + class="static_wall", + color="green" + }, + { + x=1, + y=11, + class="static_wall", + color="green" + }, + { + x=2, + y=11, + class="static_wall", + color="green" + }, + { + x=3, + y=11, + class="static_wall", + color="green" + }, + { + x=4, + y=11, + class="static_wall", + color="green" + }, + { + x=5, + y=11, + class="static_wall", + color="green" + }, + { + x=6, + y=11, + class="static_wall", + color="green" + }, + { + x=7, + y=11, + class="static_wall", + color="green" + }, + { + x=8, + y=11, + class="static_wall", + color="green" + }, + { + x=9, + y=11, + class="static_wall", + color="green" + }, + { + x=10, + y=11, + class="static_wall", + color="green" + }, + { + x=11, + y=5, + class="static_wall", + color="green" + }, + { + x=5, + y=7, + class="box", + color="green" + }, + { + x=11, + y=11, + class="static_wall", + color="blue" + }, + { + x=11, + y=10, + class="static_wall", + color="blue" + }, + { + x=11, + y=9, + class="static_wall", + color="blue" + }, + { + x=11, + y=8, + class="static_wall", + color="blue" + }, + { + x=11, + y=7, + class="static_wall", + color="blue" + }, + { + x=11, + y=6, + class="static_wall", + color="blue" + }, + { + x=11, + y=4, + class="static_wall", + color="blue" + }, + { + x=11, + y=3, + class="static_wall", + color="blue" + }, + { + x=11, + y=2, + class="static_wall", + color="blue" + }, + { + x=11, + y=1, + class="static_wall", + color="blue" + }, + { + x=10, + y=1, + class="static_wall", + color="blue" + }, + { + x=9, + y=1, + class="static_wall", + color="blue" + }, + { + x=8, + y=1, + class="static_wall", + color="blue" + }, + { + x=7, + y=1, + class="static_wall", + color="blue" + }, + { + x=6, + y=1, + class="static_wall", + color="blue" + }, + { + x=5, + y=1, + class="static_wall", + color="blue" + }, + { + x=4, + y=1, + class="static_wall", + color="blue" + }, + { + x=3, + y=1, + class="static_wall", + color="blue" + }, + { + x=2, + y=1, + class="static_wall", + color="blue" + }, + { + x=1, + y=1, + class="static_wall", + color="blue" + }, + { + x=1, + y=2, + class="static_wall", + color="blue" + }, + { + x=1, + y=3, + class="static_wall", + color="blue" + }, + { + x=1, + y=4, + class="static_wall", + color="blue" + }, + { + x=1, + y=5, + class="static_wall", + color="blue" + }, + { + x=1, + y=6, + class="static_wall", + color="blue" + }, + { + x=1, + y=7, + class="static_wall", + color="blue" + }, + { + x=1, + y=8, + class="static_wall", + color="blue" + }, + { + x=1, + y=9, + class="static_wall", + color="blue" + }, + { + x=1, + y=10, + class="static_wall", + color="blue" + }, + { + x=1, + y=11, + class="static_wall", + color="blue" + }, + { + x=2, + y=11, + class="static_wall", + color="blue" + }, + { + x=3, + y=11, + class="static_wall", + color="blue" + }, + { + x=4, + y=11, + class="static_wall", + color="blue" + }, + { + x=5, + y=11, + class="static_wall", + color="blue" + }, + { + x=6, + y=11, + class="static_wall", + color="blue" + }, + { + x=7, + y=11, + class="static_wall", + color="blue" + }, + { + x=8, + y=11, + class="static_wall", + color="blue" + }, + { + x=9, + y=11, + class="static_wall", + color="blue" + }, + { + x=10, + y=11, + class="static_wall", + color="blue" + }, + { + x=11, + y=5, + class="static_wall", + color="blue" + }, + { + x=6, + y=6, + class="box", + color="blue" + }, + { + x=11, + y=11, + class="static_wall", + color="red" + }, + { + x=11, + y=10, + class="static_wall", + color="red" + }, + { + x=11, + y=9, + class="static_wall", + color="red" + }, + { + x=11, + y=8, + class="static_wall", + color="red" + }, + { + x=11, + y=7, + class="static_wall", + color="red" + }, + { + x=11, + y=6, + class="static_wall", + color="red" + }, + { + x=11, + y=4, + class="static_wall", + color="red" + }, + { + x=11, + y=3, + class="static_wall", + color="red" + }, + { + x=11, + y=2, + class="static_wall", + color="red" + }, + { + x=11, + y=1, + class="static_wall", + color="red" + }, + { + x=10, + y=1, + class="static_wall", + color="red" + }, + { + x=9, + y=1, + class="static_wall", + color="red" + }, + { + x=8, + y=1, + class="static_wall", + color="red" + }, + { + x=7, + y=1, + class="static_wall", + color="red" + }, + { + x=6, + y=1, + class="static_wall", + color="red" + }, + { + x=5, + y=1, + class="static_wall", + color="red" + }, + { + x=4, + y=1, + class="static_wall", + color="red" + }, + { + x=3, + y=1, + class="static_wall", + color="red" + }, + { + x=2, + y=1, + class="static_wall", + color="red" + }, + { + x=1, + y=1, + class="static_wall", + color="red" + }, + { + x=1, + y=2, + class="static_wall", + color="red" + }, + { + x=1, + y=3, + class="static_wall", + color="red" + }, + { + x=1, + y=4, + class="static_wall", + color="red" + }, + { + x=1, + y=5, + class="static_wall", + color="red" + }, + { + x=1, + y=6, + class="static_wall", + color="red" + }, + { + x=1, + y=7, + class="static_wall", + color="red" + }, + { + x=1, + y=8, + class="static_wall", + color="red" + }, + { + x=1, + y=9, + class="static_wall", + color="red" + }, + { + x=1, + y=10, + class="static_wall", + color="red" + }, + { + x=1, + y=11, + class="static_wall", + color="red" + }, + { + x=2, + y=11, + class="static_wall", + color="red" + }, + { + x=3, + y=11, + class="static_wall", + color="red" + }, + { + x=4, + y=11, + class="static_wall", + color="red" + }, + { + x=5, + y=11, + class="static_wall", + color="red" + }, + { + x=6, + y=11, + class="static_wall", + color="red" + }, + { + x=7, + y=11, + class="static_wall", + color="red" + }, + { + x=8, + y=11, + class="static_wall", + color="red" + }, + { + x=9, + y=11, + class="static_wall", + color="red" + }, + { + x=10, + y=11, + class="static_wall", + color="red" + }, + { + x=11, + y=5, + class="static_wall", + color="red" + }, + { + x=5, + y=6, + class="box", + color="red" + }, + { + x=6, + y=8, + class="player", + color="green" + }, + { + x=6, + y=8, + class="player", + color="blue" + }, + { + x=6, + y=8, + class="player", + color="red" + } +} +} \ No newline at end of file diff --git a/rooms/room_01_05.sav b/rooms/room_01_05.sav new file mode 100644 index 0000000..3e784f7 --- /dev/null +++ b/rooms/room_01_05.sav @@ -0,0 +1,4 @@ +{ +objects={ +} +} \ No newline at end of file diff --git a/rooms/room_03_08.sav b/rooms/room_03_08.sav new file mode 100644 index 0000000..3e784f7 --- /dev/null +++ b/rooms/room_03_08.sav @@ -0,0 +1,4 @@ +{ +objects={ +} +} \ No newline at end of file diff --git a/rooms/world.sav b/rooms/world.sav index fb9521d..5cad4a2 100644 --- a/rooms/world.sav +++ b/rooms/world.sav @@ -1,157 +1,172 @@ { rooms={ { - name="start", + x=9, y=11, - x=9 + name="start" }, { - name="3", + x=10, y=10, - x=10 + name="3" }, { - name="5", + x=12, y=10, - x=12 + name="5" }, { - name="village_1", + x=12, y=9, - x=12 + name="village_1" }, { - name="village_2", + x=12, y=8, - x=12 + name="village_2" }, { - name="village_3", + x=13, y=8, - x=13 + name="village_3" }, { - name="village_4", + x=11, y=8, - x=11 + name="village_4" }, { - name="yellow_1", + x=11, y=7, - x=11 + name="yellow_1" }, { - name="yellow_3", + x=11, y=6, - x=11 + name="yellow_3" }, { - name="yellow_2", + x=12, y=7, - x=12 + name="yellow_2" }, { - name="yellow_4", + x=11, y=5, - x=11 + name="yellow_4" }, { - name="yellow_5", + x=11, y=4, - x=11 + name="yellow_5" }, { - name="yellow_6", + x=10, y=5, - x=10 + name="yellow_6" }, { - name="default", + x=1, y=1, - x=1 + name="default" }, { - name="old_yellow_3", + x=3, y=1, - x=3 + name="old_yellow_3" }, { - name="test_patt", + x=5, y=1, - x=5 + name="test_patt" }, { - name="test_patt_update", + x=7, y=1, - x=7 + name="test_patt_update" }, { - name="white_asymmetrical", + x=9, y=1, - x=9 + name="white_asymmetrical" }, { - name="white_ok", + x=11, y=1, - x=11 + name="white_ok" }, { - name="white_primary", + x=13, y=1, - x=13 + name="white_primary" }, { - name="yellow_arches", + x=15, y=1, - x=15 + name="yellow_arches" }, { - name="yellow_asymmetrical", + x=17, y=1, - x=17 + name="yellow_asymmetrical" }, { - name="yellow_cc_moustache", + x=1, y=3, - x=1 + name="yellow_cc_moustache" }, { - name="yellow_color_changing_levvel_1", + x=3, y=3, - x=3 + name="yellow_color_changing_levvel_1" }, { - name="yellow_smile", + x=7, y=3, - x=7 + name="yellow_smile" }, { - name="2", + x=9, y=10, - x=9 + name="2" }, { - name="room_11_09", + x=11, y=9, - x=11 + name="room_11_09" }, { - name="yellow_skull", + x=9, y=3, - x=9 + name="yellow_skull" }, { - name="jorge_room", + x=5, y=5, - x=5 + name="jorge_room" }, { - name="4", + x=11, y=10, - x=11 + name="4" + }, + { + x=1, + y=5, + name="room_01_05" + }, + { + x=2, + y=8, + name="ok" + }, + { + x=3, + y=8, + name="room_03_08" } }, -lastRoom="yellow_4", +lastRoom="room_03_08", width=18, height=18 } \ No newline at end of file