diff --git a/src/main.js b/src/main.js index db5810e..58efdb9 100644 --- a/src/main.js +++ b/src/main.js @@ -64,17 +64,17 @@ const SHELL_BEAM_Y = [432, 656, 877, 1094].map((y) => y + HOUSE_Y_OFFSET) const HOUSE_TOP = FLOOR_SLOTS[0].y const HOUSE_BOTTOM = FLOOR_SLOTS[FLOOR_COUNT - 1].y + FLOOR_SLOTS[FLOOR_COUNT - 1].h -const STATUS_Y = 1540 +const STATUS_Y = 1538 // A true rooftop level above the shell, rather than a tiny room inside the gable. const ROOF_ROOM_BOUNDS = { - x: 410, - y: 18, - width: 302, - height: 126 + x: 155, + y: 42, + width: 812, + height: 168 } -const ROOF_LIFT_STOP_Y = ROOF_ROOM_BOUNDS.y + Math.round(ROOF_ROOM_BOUNDS.height * 0.84) +const ROOF_LIFT_STOP_Y = ROOF_ROOM_BOUNDS.y + ROOF_ROOM_BOUNDS.height - 24 const ELEVATOR_SHAFT_TOP = ROOF_LIFT_STOP_Y - 48 const ELEVATOR_CAR_W = 82 @@ -199,7 +199,7 @@ function makeRoofRoom() { width, height, walkBand: { - minY: y + Math.round(height * 0.72), + minY: y + Math.round(height * 0.68), maxY: y + height - 8, homeY: ROOF_LIFT_STOP_Y } @@ -229,7 +229,7 @@ function elevatorStopY(room) { function elevatorEntry(room) { if (room.side === 'center') { return { - x: room.x + Math.round(room.width * 0.68), + x: TOWER_CENTER_X + 118, y: room.walkBand.homeY } } @@ -605,77 +605,86 @@ class HouseScene extends Phaser.Scene { const room = ROOM_BY_ID.get('roof-garden') const graphics = this.add.graphics().setDepth(30) - const inset = 8 - const backInset = 42 - const wallTop = room.y + 7 - const backTop = room.y + 18 + const left = room.x + const right = room.x + room.width + const top = room.y + const bottom = room.y + room.height + const backLeft = left + 84 + const backRight = right - 84 const horizonY = room.walkBand.minY - const bottomY = room.y + room.height - 6 - const left = room.x + inset - const right = room.x + room.width - inset - const backLeft = room.x + backInset - const backRight = room.x + room.width - backInset - // Open-air sky panel and rooftop turf deck. - graphics.fillStyle(0xcfefff, 1) - graphics.fillRoundedRect(room.x, room.y, room.width, room.height, 18) + // Open rooftop terrace. The transparent sky lets the pink roof remain + // visible behind it while the green deck makes the playable level obvious. + graphics.fillStyle(0xffffff, 0.72) + graphics.fillRoundedRect(left, top, room.width, room.height, 24) - graphics.fillStyle(0xbce8ff, 1) - graphics.fillRect(backLeft, backTop, backRight - backLeft, horizonY - backTop) - - graphics.fillStyle(0x8fd47f, 1) + graphics.fillStyle(0x94d985, 1) graphics.fillPoints([ new Phaser.Geom.Point(backLeft, horizonY), new Phaser.Geom.Point(backRight, horizonY), - new Phaser.Geom.Point(right, bottomY), - new Phaser.Geom.Point(left, bottomY) + new Phaser.Geom.Point(right - 18, bottom - 8), + new Phaser.Geom.Point(left + 18, bottom - 8) ], true) - // Railing so the garden reads as a rooftop terrace. - graphics.lineStyle(4, 0xffd1df, 1) - graphics.lineBetween(left + 8, horizonY - 16, right - 8, horizonY - 16) - graphics.lineBetween(left + 12, horizonY - 16, left + 12, bottomY) - graphics.lineBetween(right - 12, horizonY - 16, right - 12, bottomY) + // Pink rooftop railing. + graphics.lineStyle(6, 0xf3a7c1, 1) + graphics.lineBetween(left + 24, horizonY - 22, right - 24, horizonY - 22) + graphics.lineBetween(left + 28, horizonY - 22, left + 28, bottom - 10) + graphics.lineBetween(right - 28, horizonY - 22, right - 28, bottom - 10) - // Planters. - graphics.fillStyle(0xf3c797, 1) - graphics.fillRoundedRect(left + 16, horizonY - 20, 58, 18, 5) - graphics.fillRoundedRect(right - 74, horizonY - 20, 58, 18, 5) + // Planters along the back edge. + graphics.fillStyle(0xf2c08d, 1) + graphics.fillRoundedRect(left + 56, horizonY - 27, 104, 22, 6) + graphics.fillRoundedRect(right - 160, horizonY - 27, 104, 22, 6) const flowers = [ - { x: left + 30, y: horizonY - 27, color: '#ff7fa9' }, - { x: left + 48, y: horizonY - 34, color: '#ffd86a' }, - { x: right - 48, y: horizonY - 33, color: '#b78cff' }, - { x: right - 28, y: horizonY - 27, color: '#ff8f7e' } + { x: left + 78, y: horizonY - 37, color: '#ff7fa9' }, + { x: left + 104, y: horizonY - 43, color: '#ffd86a' }, + { x: left + 132, y: horizonY - 36, color: '#b78cff' }, + { x: right - 132, y: horizonY - 36, color: '#ff8f7e' }, + { x: right - 104, y: horizonY - 44, color: '#ffd86a' }, + { x: right - 78, y: horizonY - 38, color: '#b78cff' } ] flowers.forEach((flower) => { this.add.text(flower.x, flower.y, '✿', { fontFamily: 'Arial', - fontSize: '20px', + fontSize: '23px', color: flower.color }).setOrigin(0.5).setDepth(32) }) - // Bench, offset left so the lift exit on the right remains clear. - graphics.fillStyle(0xe5b982, 1) - graphics.fillRoundedRect(room.x + 92, horizonY - 9, 74, 9, 4) - graphics.fillRect(room.x + 99, horizonY, 6, 16) - graphics.fillRect(room.x + 153, horizonY, 6, 16) + // Bench on the left, keeping the lift landing clear in the centre/right. + graphics.fillStyle(0xe3b47c, 1) + graphics.fillRoundedRect(left + 218, horizonY - 12, 112, 12, 5) + graphics.fillRect(left + 230, horizonY, 7, 20) + graphics.fillRect(left + 309, horizonY, 7, 20) - graphics.lineStyle(3, 0xd5a4bd, 1) - graphics.strokeRoundedRect(room.x, room.y, room.width, room.height, 18) - graphics.lineBetween(left, bottomY, backLeft, horizonY) - graphics.lineBetween(right, bottomY, backRight, horizonY) + // Lift landing marker aligned with the real sixth elevator stop. + graphics.fillStyle(0xfff2f7, 1) + graphics.fillRoundedRect(TOWER_CENTER_X - 56, horizonY - 38, 112, 44, 10) + graphics.lineStyle(4, 0xd99ab6, 1) + graphics.strokeRoundedRect(TOWER_CENTER_X - 56, horizonY - 38, 112, 44, 10) - this.add.text(room.x + 12, room.y + 9, 'Rooftop Garden', { + graphics.lineStyle(4, 0xd5a4bd, 1) + graphics.strokeRoundedRect(left, top, room.width, room.height, 24) + + this.add.text(left + 20, top + 14, 'Rooftop Garden', { fontFamily: 'Arial Rounded MT Bold, ui-rounded, sans-serif', - fontSize: '15px', - color: '#5f7552', + fontSize: '19px', + color: '#56734e', fontStyle: 'bold', + backgroundColor: 'rgba(255,255,255,0.90)', + padding: { x: 8, y: 4 } + }).setDepth(33) + + this.add.text(right - 22, top + 17, 'hold to visit', { + fontFamily: 'Arial Rounded MT Bold, ui-rounded, sans-serif', + fontSize: '14px', + color: '#8b6577', backgroundColor: 'rgba(255,255,255,0.86)', padding: { x: 6, y: 3 } - }).setDepth(33) + }).setOrigin(1, 0).setDepth(33) } buildHouseShell() { @@ -911,7 +920,9 @@ class HouseScene extends Phaser.Scene { this.updateStatus(this.currentRoom(), 'Hold for ' + room.name + '…') - this.roomHoldTimer = this.time.delayedCall(ROOM_HOLD_MS, () => { + const holdMs = room.isRoof ? 360 : ROOM_HOLD_MS + + this.roomHoldTimer = this.time.delayedCall(holdMs, () => { if ( this.roomHoldRoom?.id !== room.id || this.journeyActive @@ -1389,7 +1400,7 @@ const game = new Phaser.Game({ }) window.__DOLLHOUSE__ = { - version: '0.10.0', + version: '0.10.1', game, async resetAll() { await clearGameState() diff --git a/src/style.css b/src/style.css index 3777c6e..bfee73c 100644 --- a/src/style.css +++ b/src/style.css @@ -12,6 +12,9 @@ html, body, #app, #game { margin: 0; overflow: hidden; } +#game { + padding-top: clamp(42px, 6vh, 76px); +} body { min-height: 100dvh; overscroll-behavior: none;