mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
fix: Align connecting rooms to grid with minimum 1 GU overlap
Updated room positioning algorithm to ensure all connecting rooms are properly aligned to the grid and have at least one Grid Unit overlap with the connecting edge of the parent room. Changes: - positionNorthMultiple/positionSouthMultiple: Position rooms as a group, align the starting position to grid, then place rooms side-by-side without individual alignment to prevent gaps - positionEastMultiple/positionWestMultiple: Similar approach for vertical stacking of rooms along east/west edges This ensures: - All rooms maintain proper grid alignment - Connected rooms have guaranteed minimum overlap - No gaps between adjacent rooms in multi-room connections - Room layouts match the examples in planning notes Addresses alignment issues described in new_room_layout documentation where rooms need to be positioned against the connecting edge with at least one GU overlap.
This commit is contained in:
164
js/core/rooms.js
164
js/core/rooms.js
@@ -1049,35 +1049,45 @@ function validateMultipleConnections(direction, currentRoom, connectedRooms, cur
|
||||
|
||||
/**
|
||||
* Position multiple rooms to the north of current room
|
||||
* CRITICAL: Ensures all connected rooms have at least 1 GU overlap with current room's edge
|
||||
*/
|
||||
function positionNorthMultiple(currentRoom, connectedRooms, currentPos, dimensions) {
|
||||
const currentDim = dimensions[currentRoom];
|
||||
const positions = {};
|
||||
|
||||
// CRITICAL: Position rooms based on where doors will be, not just centering widths
|
||||
// This ensures doors align properly between different-sized rooms
|
||||
// Calculate total width of all connected rooms
|
||||
const totalWidth = connectedRooms.reduce((sum, roomId) => {
|
||||
return sum + dimensions[roomId].widthPx;
|
||||
}, 0);
|
||||
|
||||
// Calculate where doors will be placed on current room's north wall
|
||||
// (uses same logic as placeNorthDoorsMultiple in doors.js)
|
||||
const edgeInset = TILE_SIZE * 1.5; // 48px
|
||||
const availableWidth = currentDim.widthPx - (edgeInset * 2);
|
||||
const doorCount = connectedRooms.length;
|
||||
const doorSpacing = availableWidth / (doorCount - 1);
|
||||
// Calculate starting X position to center the group over current room
|
||||
// This ensures connected rooms are distributed along current room's edge
|
||||
const groupStartX = currentPos.x + (currentDim.widthPx - totalWidth) / 2;
|
||||
|
||||
connectedRooms.forEach((roomId, index) => {
|
||||
// Align the starting position to grid
|
||||
// All rooms will be placed from this aligned start without individual alignment
|
||||
// since room widths are multiples of grid units
|
||||
const alignedGroupStart = alignToGrid(groupStartX, 0);
|
||||
|
||||
// Position each room side-by-side starting from aligned position
|
||||
// No individual alignment needed - rooms naturally align when placed from grid-aligned start
|
||||
let currentX = alignedGroupStart.x;
|
||||
|
||||
connectedRooms.forEach(roomId => {
|
||||
const connectedDim = dimensions[roomId];
|
||||
|
||||
// Calculate where the door will be on current room's north wall
|
||||
const doorX = currentPos.x + edgeInset + (doorSpacing * index);
|
||||
// Calculate Y position based on room's stacking height
|
||||
const roomY = currentPos.y - connectedDim.stackingHeightPx;
|
||||
|
||||
// Center the connected room on this door position
|
||||
const x = doorX - (connectedDim.widthPx / 2);
|
||||
// Align Y to grid
|
||||
const alignedY = alignToGrid(0, roomY).y;
|
||||
|
||||
// Y position is based on stacking height
|
||||
const y = currentPos.y - connectedDim.stackingHeightPx;
|
||||
// X is already aligned via group start, just use currentX
|
||||
positions[roomId] = { x: currentX, y: alignedY };
|
||||
|
||||
// Align to grid
|
||||
positions[roomId] = alignToGrid(x, y);
|
||||
// Move X position for next room (no individual alignment)
|
||||
// Since room widths are multiples of grid units, this maintains alignment
|
||||
currentX += connectedDim.widthPx;
|
||||
});
|
||||
|
||||
return positions;
|
||||
@@ -1100,35 +1110,40 @@ function positionSouthSingle(currentRoom, connectedRoom, currentPos, dimensions)
|
||||
|
||||
/**
|
||||
* Position multiple rooms to the south of current room
|
||||
* CRITICAL: Ensures all connected rooms have at least 1 GU overlap with current room's edge
|
||||
*/
|
||||
function positionSouthMultiple(currentRoom, connectedRooms, currentPos, dimensions) {
|
||||
const currentDim = dimensions[currentRoom];
|
||||
const positions = {};
|
||||
|
||||
// CRITICAL: Position rooms based on where doors will be, not just centering widths
|
||||
// This ensures doors align properly between different-sized rooms
|
||||
// Calculate total width of all connected rooms
|
||||
const totalWidth = connectedRooms.reduce((sum, roomId) => {
|
||||
return sum + dimensions[roomId].widthPx;
|
||||
}, 0);
|
||||
|
||||
// Calculate where doors will be placed on current room's south wall
|
||||
// (uses same logic as placeSouthDoorsMultiple in doors.js)
|
||||
const edgeInset = TILE_SIZE * 1.5; // 48px
|
||||
const availableWidth = currentDim.widthPx - (edgeInset * 2);
|
||||
const doorCount = connectedRooms.length;
|
||||
const doorSpacing = availableWidth / (doorCount - 1);
|
||||
// Calculate starting X position to center the group over current room
|
||||
// This ensures connected rooms are distributed along current room's edge
|
||||
const groupStartX = currentPos.x + (currentDim.widthPx - totalWidth) / 2;
|
||||
|
||||
connectedRooms.forEach((roomId, index) => {
|
||||
// Align the starting position to grid
|
||||
// All rooms will be placed from this aligned start without individual alignment
|
||||
const alignedGroupStart = alignToGrid(groupStartX, 0);
|
||||
|
||||
// Position each room side-by-side starting from aligned position
|
||||
let currentX = alignedGroupStart.x;
|
||||
const y = currentPos.y + currentDim.stackingHeightPx;
|
||||
|
||||
// Align Y to grid
|
||||
const alignedY = alignToGrid(0, y).y;
|
||||
|
||||
connectedRooms.forEach(roomId => {
|
||||
const connectedDim = dimensions[roomId];
|
||||
|
||||
// Calculate where the door will be on current room's south wall
|
||||
const doorX = currentPos.x + edgeInset + (doorSpacing * index);
|
||||
// X is already aligned via group start, Y is same for all rooms
|
||||
positions[roomId] = { x: currentX, y: alignedY };
|
||||
|
||||
// Center the connected room on this door position
|
||||
const x = doorX - (connectedDim.widthPx / 2);
|
||||
|
||||
// Y position below current room
|
||||
const y = currentPos.y + currentDim.stackingHeightPx;
|
||||
|
||||
// Align to grid
|
||||
positions[roomId] = alignToGrid(x, y);
|
||||
// Move X position for next room (no individual alignment)
|
||||
currentX += connectedDim.widthPx;
|
||||
});
|
||||
|
||||
return positions;
|
||||
@@ -1151,34 +1166,42 @@ function positionEastSingle(currentRoom, connectedRoom, currentPos, dimensions)
|
||||
|
||||
/**
|
||||
* Position multiple rooms to the east of current room
|
||||
* CRITICAL: Ensures all connected rooms have at least 1 GU overlap with current room's edge
|
||||
*/
|
||||
function positionEastMultiple(currentRoom, connectedRooms, currentPos, dimensions) {
|
||||
const currentDim = dimensions[currentRoom];
|
||||
const positions = {};
|
||||
|
||||
// CRITICAL: Position rooms based on where doors will be, not just stacking vertically
|
||||
// This ensures doors align properly between different-sized rooms
|
||||
// Calculate total height of all connected rooms (using stacking height)
|
||||
const totalHeight = connectedRooms.reduce((sum, roomId) => {
|
||||
return sum + dimensions[roomId].stackingHeightPx;
|
||||
}, 0);
|
||||
|
||||
// Position to the right
|
||||
// Calculate starting Y position to center the group along current room's edge
|
||||
// This ensures connected rooms are distributed along current room's edge
|
||||
const groupStartY = currentPos.y + (currentDim.stackingHeightPx - totalHeight) / 2;
|
||||
|
||||
// Align the starting position to grid
|
||||
// All rooms will be placed from this aligned start without individual alignment
|
||||
const alignedGroupStart = alignToGrid(0, groupStartY);
|
||||
|
||||
// Position each room stacked vertically starting from aligned position
|
||||
const x = currentPos.x + currentDim.widthPx;
|
||||
|
||||
// Calculate where doors will be placed on current room's east wall
|
||||
// (uses same logic as placeEastDoorsMultiple in doors.js)
|
||||
const topY = currentPos.y + (TILE_SIZE * 2);
|
||||
const bottomY = currentPos.y + currentDim.heightPx - (TILE_SIZE * 3);
|
||||
const doorSpacing = (bottomY - topY) / (connectedRooms.length - 1);
|
||||
// Align X to grid
|
||||
const alignedX = alignToGrid(x, 0).x;
|
||||
|
||||
connectedRooms.forEach((roomId, index) => {
|
||||
let currentY = alignedGroupStart.y;
|
||||
|
||||
connectedRooms.forEach(roomId => {
|
||||
const connectedDim = dimensions[roomId];
|
||||
|
||||
// Calculate where the door will be on current room's east wall
|
||||
const doorY = topY + (doorSpacing * index);
|
||||
// Y is already aligned via group start, X is same for all rooms
|
||||
positions[roomId] = { x: alignedX, y: currentY };
|
||||
|
||||
// Center the connected room on this door position vertically
|
||||
const y = doorY - (TILE_SIZE * 2); // Align with door at 2 tiles from top
|
||||
|
||||
// Align to grid
|
||||
positions[roomId] = alignToGrid(x, y);
|
||||
// Move Y position for next room (no individual alignment)
|
||||
// Since room heights are multiples of grid units, this maintains alignment
|
||||
currentY += connectedDim.stackingHeightPx;
|
||||
});
|
||||
|
||||
return positions;
|
||||
@@ -1200,34 +1223,43 @@ function positionWestSingle(currentRoom, connectedRoom, currentPos, dimensions)
|
||||
|
||||
/**
|
||||
* Position multiple rooms to the west of current room
|
||||
* CRITICAL: Ensures all connected rooms have at least 1 GU overlap with current room's edge
|
||||
*/
|
||||
function positionWestMultiple(currentRoom, connectedRooms, currentPos, dimensions) {
|
||||
const currentDim = dimensions[currentRoom];
|
||||
const positions = {};
|
||||
|
||||
// CRITICAL: Position rooms based on where doors will be, not just stacking vertically
|
||||
// This ensures doors align properly between different-sized rooms
|
||||
// Calculate total height of all connected rooms (using stacking height)
|
||||
const totalHeight = connectedRooms.reduce((sum, roomId) => {
|
||||
return sum + dimensions[roomId].stackingHeightPx;
|
||||
}, 0);
|
||||
|
||||
// Calculate where doors will be placed on current room's west wall
|
||||
// (uses same logic as placeWestDoorsMultiple in doors.js)
|
||||
const topY = currentPos.y + (TILE_SIZE * 2);
|
||||
const bottomY = currentPos.y + currentDim.heightPx - (TILE_SIZE * 3);
|
||||
const doorSpacing = (bottomY - topY) / (connectedRooms.length - 1);
|
||||
// Calculate starting Y position to center the group along current room's edge
|
||||
// This ensures connected rooms are distributed along current room's edge
|
||||
const groupStartY = currentPos.y + (currentDim.stackingHeightPx - totalHeight) / 2;
|
||||
|
||||
connectedRooms.forEach((roomId, index) => {
|
||||
// Align the starting position to grid
|
||||
// All rooms will be placed from this aligned start without individual alignment
|
||||
const alignedGroupStart = alignToGrid(0, groupStartY);
|
||||
|
||||
// Position each room stacked vertically starting from aligned position
|
||||
let currentY = alignedGroupStart.y;
|
||||
|
||||
connectedRooms.forEach(roomId => {
|
||||
const connectedDim = dimensions[roomId];
|
||||
|
||||
// Position to the left
|
||||
const x = currentPos.x - connectedDim.widthPx;
|
||||
|
||||
// Calculate where the door will be on current room's west wall
|
||||
const doorY = topY + (doorSpacing * index);
|
||||
// Align X to grid
|
||||
const alignedX = alignToGrid(x, 0).x;
|
||||
|
||||
// Center the connected room on this door position vertically
|
||||
const y = doorY - (TILE_SIZE * 2); // Align with door at 2 tiles from top
|
||||
// Y is already aligned via group start
|
||||
positions[roomId] = { x: alignedX, y: currentY };
|
||||
|
||||
// Align to grid
|
||||
positions[roomId] = alignToGrid(x, y);
|
||||
// Move Y position for next room (no individual alignment)
|
||||
// Since room heights are multiples of grid units, this maintains alignment
|
||||
currentY += connectedDim.stackingHeightPx;
|
||||
});
|
||||
|
||||
return positions;
|
||||
|
||||
Reference in New Issue
Block a user