diff --git a/src/main.js b/src/main.js index f3b9a26..37f90c9 100644 --- a/src/main.js +++ b/src/main.js @@ -134,15 +134,6 @@ const ARCHITECTURE_CROPS = { floorEdge: { x: 210, y: 306, w: 1007, h: 87 } } -const HOUSE_SHELL_CROPS = { - roof: { x: 0, y: 0, w: 1122, h: 245 }, - leftPost: { x: 24, y: 240, w: 76, h: 150 }, - rightPost: { x: 1020, y: 240, w: 76, h: 150 }, - beamLeft: { x: 72, y: 397, w: 400, h: 64 }, - beamRight: { x: 638, y: 397, w: 408, h: 64 }, - foundation: { x: 0, y: 1250, w: 1122, h: 152 } -} - const ROOM_SKINS = { disco: { wallpaper: 'wallpaper-disco', floor: 'floor-disco' }, 'top-bedroom': { wallpaper: 'wallpaper-topBedroom', floor: 'floor-lightWood' }, @@ -320,7 +311,15 @@ class HouseScene extends Phaser.Scene { this.load.image('architecture-sheet', '/assets/architecture-sheet.png') this.load.image('wallpaper-sheet', '/assets/wallpaper-sheet.png') this.load.image('floor-sheet', '/assets/floor-sheet.png') - this.load.image('house-shell-sheet', '/assets/house-shell-overlay.png') + this.load.image('shell-roof', '/assets/shell/roof_full.png') + this.load.image('shell-tower', '/assets/shell/central_tower_full.png') + this.load.image('shell-post-seg', '/assets/shell/outer_post_segment.png') + this.load.image('shell-post-joint', '/assets/shell/outer_post_joint.png') + this.load.image('shell-beam-left', '/assets/shell/floor_beam_left.png') + this.load.image('shell-beam-right', '/assets/shell/floor_beam_right.png') + this.load.image('shell-bracket-left', '/assets/shell/inner_bracket_left.png') + this.load.image('shell-foundation-left', '/assets/shell/foundation_left.png') + this.load.image('shell-foundation-right', '/assets/shell/foundation_right.png') this.load.image( 'elevator-shaft', 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(buildElevatorSvg()) @@ -348,10 +347,6 @@ class HouseScene extends Phaser.Scene { cropTexture(this, 'architecture-sheet', 'architecture-' + key, rect) }) - Object.entries(HOUSE_SHELL_CROPS).forEach(([key, rect]) => { - cropTexture(this, 'house-shell-sheet', 'house-shell-' + key, rect) - }) - const saved = await loadGameState() this.state = saved?.version === 3 && ROOM_BY_ID.has(saved.player?.roomId) ? saved @@ -569,55 +564,88 @@ class HouseScene extends Phaser.Scene { buildHouseShell() { const shellDepth = 7 + const towerDepth = 8 const stackHeight = FLOOR_COUNT * FLOOR_H + (FLOOR_COUNT - 1) * FLOOR_GAP const stackBottom = HOUSE_TOP + stackHeight - // Decorative roof/cap. It is intentionally compressed vertically so it - // fits above the responsive room stack without stealing playable space. - this.add.image(WIDTH / 2, HOUSE_TOP + 10, 'house-shell-roof') + const leftOuterX = LEFT_X - 10 + const rightOuterX = RIGHT_X + BANK_W + 10 + const leftBankCenter = LEFT_X + BANK_W / 2 + const rightBankCenter = RIGHT_X + BANK_W / 2 + const towerCenterX = ELEVATOR_X + ELEVATOR_W / 2 + + // Full roof artwork keeps its native proportions instead of being cropped + // from a stretched master sheet. + this.add.image(WIDTH / 2, HOUSE_TOP + 8, 'shell-roof') .setOrigin(0.5, 1) - .setDisplaySize(1000, 96) + .setDisplaySize(1000, 116) .setDepth(shellDepth) - // Continuous outer posts make the ten room openings read as one house. - this.add.image(LEFT_X - 17, HOUSE_TOP + stackHeight / 2, 'house-shell-leftPost') - .setDisplaySize(46, stackHeight + 14) - .setDepth(shellDepth) + // The center tower is independent from the moving elevator shaft/car. + // The functional shaft renders above this trim so animation remains clear. + this.add.image(towerCenterX, HOUSE_TOP - 34, 'shell-tower') + .setOrigin(0.5, 0) + .setDisplaySize(206, stackHeight + 92) + .setDepth(towerDepth) - this.add.image( - RIGHT_X + BANK_W + 17, - HOUSE_TOP + stackHeight / 2, - 'house-shell-rightPost' - ) - .setDisplaySize(46, stackHeight + 14) - .setDepth(shellDepth) + // Build the outside frame from one clean repeatable post segment per room. + for (let floor = 0; floor < FLOOR_COUNT; floor += 1) { + const segmentY = floorY(floor) + FLOOR_H / 2 - // Reuse the generated decorative floor beam at every storey boundary. - for (let floor = 0; floor < FLOOR_COUNT - 1; floor += 1) { - const beamY = floorY(floor) + FLOOR_H + FLOOR_GAP / 2 - - this.add.image( - LEFT_X + BANK_W / 2, - beamY, - 'house-shell-beamLeft' - ) - .setDisplaySize(BANK_W + 26, 28) + this.add.image(leftOuterX, segmentY, 'shell-post-seg') + .setDisplaySize(34, FLOOR_H + 8) .setDepth(shellDepth) - this.add.image( - RIGHT_X + BANK_W / 2, - beamY, - 'house-shell-beamRight' - ) - .setDisplaySize(BANK_W + 26, 28) + this.add.image(rightOuterX, segmentY, 'shell-post-seg') + .setDisplaySize(34, FLOOR_H + 8) + .setFlipX(true) .setDepth(shellDepth) } - // Bottom plinth/foundation ties both banks and the lift together. - this.add.image(WIDTH / 2, stackBottom - 3, 'house-shell-foundation') + // Joints and beams stay at natural floor boundaries regardless of viewport. + for (let floor = 0; floor < FLOOR_COUNT - 1; floor += 1) { + const beamY = floorY(floor) + FLOOR_H + FLOOR_GAP / 2 + const bracketY = floorY(floor) + FLOOR_H - 1 + + this.add.image(leftOuterX, beamY, 'shell-post-joint') + .setDisplaySize(42, 28) + .setDepth(shellDepth + 1) + + this.add.image(rightOuterX, beamY, 'shell-post-joint') + .setDisplaySize(42, 28) + .setFlipX(true) + .setDepth(shellDepth + 1) + + this.add.image(leftBankCenter, beamY, 'shell-beam-left') + .setDisplaySize(BANK_W + 24, 27) + .setDepth(shellDepth + 1) + + this.add.image(rightBankCenter, beamY, 'shell-beam-right') + .setDisplaySize(BANK_W + 24, 27) + .setDepth(shellDepth + 1) + + this.add.image(LEFT_X + BANK_W + 3, bracketY, 'shell-bracket-left') + .setOrigin(1, 0) + .setDisplaySize(20, 22) + .setDepth(shellDepth + 1) + + this.add.image(RIGHT_X - 3, bracketY, 'shell-bracket-left') + .setOrigin(0, 0) + .setFlipX(true) + .setDisplaySize(20, 22) + .setDepth(shellDepth + 1) + } + + // Split foundations leave the tower/plinth free to define the centre. + this.add.image(leftBankCenter, stackBottom + 7, 'shell-foundation-left') .setOrigin(0.5, 0) - .setDisplaySize(1000, 52) - .setDepth(shellDepth) + .setDisplaySize(BANK_W + 54, 48) + .setDepth(shellDepth + 1) + + this.add.image(rightBankCenter, stackBottom + 7, 'shell-foundation-right') + .setOrigin(0.5, 0) + .setDisplaySize(BANK_W + 54, 48) + .setDepth(shellDepth + 1) } buildElevator() { @@ -1251,7 +1279,7 @@ const game = new Phaser.Game({ }) window.__DOLLHOUSE__ = { - version: '0.7.0', + version: '0.7.1', game, async resetAll() { await clearGameState()