From af6f9ec7e5aa5f8642fb835fbbc745db8d5b1ee7 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 22 Sep 2026 00:45:45 +0000 Subject: [PATCH] Make roof gable a playable disco room --- src/main.js | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 3 deletions(-) diff --git a/src/main.js b/src/main.js index 8f7f702..35f7eb7 100644 --- a/src/main.js +++ b/src/main.js @@ -64,6 +64,13 @@ 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 = 1352 +const ROOF_ROOM_BOUNDS = { + x: 470, + y: 72, + width: 182, + height: 132 +} + const ELEVATOR_CAR_W = 82 const ELEVATOR_CAR_H = 90 const ELEVATOR_OPENING_W = 78 @@ -129,6 +136,7 @@ const ARCHITECTURE_CROPS = { const ROOM_SKINS = { disco: { wallpaper: 'wallpaper-disco', floor: 'floor-disco' }, + 'top-lounge': { wallpaper: 'wallpaper-living', floor: 'floor-lightWood' }, 'top-bedroom': { wallpaper: 'wallpaper-topBedroom', floor: 'floor-lightWood' }, bedroom: { wallpaper: 'wallpaper-bedroom', floor: 'floor-lightWood' }, study: { wallpaper: 'wallpaper-study', floor: 'floor-warmWood' }, @@ -171,8 +179,31 @@ function makeRoom(id, name, floor, side, color) { } } +function makeRoofRoom() { + const { x, y, width, height } = ROOF_ROOM_BOUNDS + + return { + id: 'disco', + name: 'Disco', + floor: -1, + side: 'center', + isRoof: true, + color: 0xf1e4ff, + x, + y, + width, + height, + walkBand: { + minY: y + Math.round(height * 0.70), + maxY: y + height - 8, + homeY: y + Math.round(height * 0.84) + } + } +} + const ROOMS = [ - makeRoom('disco', 'Disco', 0, 'left', 0xf1e4ff), + makeRoofRoom(), + makeRoom('top-lounge', 'Top Lounge', 0, 'left', 0xe9f5ff), makeRoom('top-bedroom', 'Top Bedroom', 0, 'right', 0xffe8f1), makeRoom('bedroom', 'Bedroom', 1, 'left', 0xffeef4), makeRoom('study', 'Study', 1, 'right', 0xfff4df), @@ -182,15 +213,22 @@ const ROOMS = [ makeRoom('bathroom', 'Bathroom', 3, 'right', 0xe5f4ff), makeRoom('garage', 'Garage', 4, 'left', 0xe8eef5), makeRoom('utility', 'Utility', 4, 'right', 0xfff0df) -] const ROOM_BY_ID = new Map(ROOMS.map((room) => [room.id, room])) function elevatorStopY(room) { + if (room.isRoof) return room.walkBand.homeY return room.y + Math.round(room.height / 2) } function elevatorEntry(room) { + if (room.side === 'center') { + return { + x: room.x + Math.round(room.width * 0.68), + y: room.walkBand.homeY + } + } + return { x: room.side === 'left' ? room.x + room.width - 24 : room.x + 24, y: room.walkBand.homeY @@ -355,6 +393,7 @@ class HouseScene extends Phaser.Scene { this.drawHouse() this.buildHouseShell() + this.drawRoofRoom() this.buildElevator() this.buildUi() this.spawnPlayer() @@ -405,6 +444,8 @@ class HouseScene extends Phaser.Scene { graphics.fillRect(36, 220, 1050, HOUSE_BOTTOM - 220) for (const room of ROOMS) { + if (room.isRoof) continue + const skin = ROOM_SKINS[room.id] const inset = 7 const sideInset = Math.round(room.width * 0.20) @@ -545,6 +586,95 @@ class HouseScene extends Phaser.Scene { } + drawRoofRoom() { + const room = ROOM_BY_ID.get('disco') + const skin = ROOM_SKINS.disco + const graphics = this.add.graphics().setDepth(9) + + const inset = 7 + const backInset = 28 + const wallTop = room.y + 8 + const backTop = room.y + 18 + const horizonY = room.y + Math.round(room.height * 0.70) + const bottomY = room.y + room.height - 7 + const left = room.x + inset + const right = room.x + room.width - inset + const backLeft = room.x + backInset + const backRight = room.x + room.width - backInset + + // Cut a playable attic/disco opening into the cream gable. + graphics.fillStyle(room.color, 1) + graphics.fillRoundedRect(room.x, room.y, room.width, room.height, 18) + + this.add.image( + room.x + room.width / 2, + backTop + (horizonY - backTop) / 2, + skin.wallpaper + ) + .setDisplaySize(backRight - backLeft, horizonY - backTop) + .setDepth(10) + + this.addMaskedImage( + room, + skin.wallpaper, + [ + { x: left, y: wallTop }, + { x: backLeft, y: backTop }, + { x: backLeft, y: horizonY }, + { x: left, y: bottomY } + ], + 10, + 0xffedf5 + ) + + this.addMaskedImage( + room, + skin.wallpaper, + [ + { x: backRight, y: backTop }, + { x: right, y: wallTop }, + { x: right, y: bottomY }, + { x: backRight, y: horizonY } + ], + 10, + 0xf2f6ff + ) + + this.addMaskedImage( + room, + skin.floor, + [ + { x: backLeft, y: horizonY }, + { x: backRight, y: horizonY }, + { x: right, y: bottomY }, + { x: left, y: bottomY } + ], + 11 + ) + + this.add.image( + room.x + room.width / 2, + horizonY, + 'architecture-skirting' + ) + .setDisplaySize(backRight - backLeft + 4, 9) + .setDepth(12) + + 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) + + this.add.text(room.x + 12, room.y + 10, 'Disco ♪', { + fontFamily: 'Arial Rounded MT Bold, ui-rounded, sans-serif', + fontSize: '14px', + color: '#765466', + fontStyle: 'bold', + backgroundColor: 'rgba(255,255,255,0.82)', + padding: { x: 5, y: 2 } + }).setDepth(13) + } + buildHouseShell() { const shellDepth = 7 const towerDepth = 8 @@ -911,6 +1041,12 @@ class HouseScene extends Phaser.Scene { 1 ) + if (room.isRoof) { + this.player.setScale(Phaser.Math.Linear(0.20, 0.24, t)) + this.player.setDepth(299) + return + } + this.player.setScale(Phaser.Math.Linear(0.34, 0.40, t)) this.player.setDepth(300 + room.floor) } @@ -1239,7 +1375,7 @@ const game = new Phaser.Game({ }) window.__DOLLHOUSE__ = { - version: '0.8.1', + version: '0.9.0', game, async resetAll() { await clearGameState()