Add drag painting to level editor
This commit is contained in:
parent
fa0bada313
commit
c3f5aafd77
6 changed files with 934 additions and 66 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue