Add white room browsing mode

This commit is contained in:
Your Name 2026-08-12 02:55:29 -04:00
parent 794b4dc162
commit 3c5e6daf06
4 changed files with 45 additions and 3 deletions

View file

@ -194,6 +194,8 @@ function love.keypressed(key)
elseif editorView ~= "world" and editorView ~= "wire" and Input.isPlayerSwitch(key) then elseif editorView ~= "world" and editorView ~= "wire" and Input.isPlayerSwitch(key) then
local c = Input.playerColor(key) local c = Input.playerColor(key)
gameWorld:switchPlayerColor(currentRoom, c) gameWorld:switchPlayerColor(currentRoom, c)
elseif editorView ~= "world" and editorView ~= "wire" and gameWorld:browseRoom(currentRoom, key) then
return
end end
-- if key == "w" then -- if key == "w" then

View file

@ -140,7 +140,8 @@ function Room:draw()
-- draw only the channels the player has. Each object just exposes sprites per -- draw only the channels the player has. Each object just exposes sprites per
-- channel via Entity:draw(channel); a door registered on all three channels -- channel via Entity:draw(channel); a door registered on all three channels
-- naturally draws its red sprite on the red pass, etc. No per-object logic. -- naturally draws its red sprite on the red pass, etc. No per-object logic.
for _, channel in ipairs(self.colorsPlayerHas) do local drawChannels = gameWorld and gameWorld.roomBrowseMode and {"red", "green", "blue"} or self.colorsPlayerHas
for _, channel in ipairs(drawChannels) do
if self.player[channel] then self.player[channel]:draw(channel) end if self.player[channel] then self.player[channel]:draw(channel) end
for _, entity in pairs(self.collideables[channel]) do entity:draw(channel) end for _, entity in pairs(self.collideables[channel]) do entity:draw(channel) end
-- The zoomed-out neighbourhood already draws every room directly. Calling -- The zoomed-out neighbourhood already draws every room directly. Calling
@ -201,8 +202,11 @@ function Room:drawWiresAt(originX, originY, cellSize, selectedCircuit, editorCol
table.sort(ordered) table.sort(ordered)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
local visibleColors = {red = false, green = false, blue = false} local showAllChannels = gameWorld and gameWorld.roomBrowseMode
for _, color in ipairs(self.colorsPlayerHas or {}) do visibleColors[color] = true end local visibleColors = {red = showAllChannels, green = showAllChannels, blue = showAllChannels}
if not showAllChannels then
for _, color in ipairs(self.colorsPlayerHas or {}) do visibleColors[color] = true end
end
local editorIsOn = editorView ~= nil and editorView ~= "off" local editorIsOn = editorView ~= nil and editorView ~= "off"
for _, circuitId in ipairs(ordered) do for _, circuitId in ipairs(ordered) do
local selected = not selectedCircuit or selectedCircuit == circuitId local selected = not selectedCircuit or selectedCircuit == circuitId

View file

@ -370,6 +370,27 @@ test("co-located colours join the active player selection", function()
"separated blue player should still select by itself") "separated blue player should still select by itself")
end) end)
test("WASD room browsing changes view without moving players", function()
local player = {x = 3, y = 4}
local roomA = {name = "a", player = {red = player}}
local roomB = {name = "b", player = {green = {x = 7, y = 8}}}
local world = setmetatable({
levels = {a = roomA, b = roomB},
roomByName = {a = {name = "a", x = 1, y = 1}, b = {name = "b", x = 2, y = 1}},
rooms = {{name = "a", x = 1, y = 1}, {name = "b", x = 2, y = 1}},
}, {__index = World})
local oldCurrentRoom, oldSetEditorRoomName = currentRoom, setEditorRoomName
currentRoom = roomA
setEditorRoomName = function() end
assertTrue(world:browseRoom(roomA, "d"))
assertTrue(currentRoom == roomB)
assertTrue(world.roomBrowseMode)
assertTrue(player.x == 3 and player.y == 4, "browsing moved the player")
currentRoom, setEditorRoomName = oldCurrentRoom, oldSetEditorRoomName
end)
test("one run cannot terminate at two different switches", function() test("one run cannot terminate at two different switches", function()
local second = switch("red", 1, 2) local second = switch("red", 1, 2)
local world, _, roomB = makeWorld(second) local world, _, roomB = makeWorld(second)

View file

@ -663,6 +663,7 @@ function World:playerJoinCheck(room, previousPositions, newPositions)
end end
function World:movePlayer(room, key) function World:movePlayer(room, key)
self.roomBrowseMode = false
local directions = { local directions = {
up = {x = 0, y = -1, axis = "y"}, down = {x = 0, y = 1, axis = "y"}, up = {x = 0, y = -1, axis = "y"}, down = {x = 0, y = 1, axis = "y"},
left = {x = -1, y = 0, axis = "x"}, right = {x = 1, y = 0, axis = "x"}, left = {x = -1, y = 0, axis = "x"}, right = {x = 1, y = 0, axis = "x"},
@ -714,6 +715,7 @@ function World:movePlayer(room, key)
end end
function World:switchPlayerColor(room, color) function World:switchPlayerColor(room, color)
self.roomBrowseMode = false
local player = room.player[color] local player = room.player[color]
if not player then if not player then
-- A colour copy can be parked in another world room. Number keys are a -- A colour copy can be parked in another world room. Number keys are a
@ -771,6 +773,19 @@ function World:switchPlayerColor(room, color)
return canSwitch return canSwitch
end end
-- Developer room browser. It changes only the displayed room; players,
-- collision, and runtime save state remain untouched.
function World:browseRoom(room, key)
local exits = {a = "left", d = "right", w = "top", s = "bottom"}
local destinationName = exits[key] and self:getNeighbor(room.name, exits[key])
local destination = destinationName and self.levels[destinationName]
if not destination then return false end
currentRoom = destination
self.roomBrowseMode = true
if setEditorRoomName then setEditorRoomName(destination.name) end
return true
end
function World:tick(room) function World:tick(room)
room:tickLocal() room:tickLocal()
self:rebuildCollision() self:rebuildCollision()