Move house lower and add reachable rooftop garden stop
This commit is contained in:
parent
0908b2a0f6
commit
26e847c89e
143
src/main.js
143
src/main.js
@ -33,7 +33,9 @@ window.addEventListener('appinstalled', () => {
|
||||
})
|
||||
|
||||
const WIDTH = 1122
|
||||
const HEIGHT = 1402
|
||||
const SHELL_HEIGHT = 1402
|
||||
const HOUSE_Y_OFFSET = 120
|
||||
const HEIGHT = 1580
|
||||
|
||||
// Native geometry measured from the approved 1122×1402 house shell.
|
||||
// Phaser fits this coordinate system to the device; the shell is no longer
|
||||
@ -51,26 +53,30 @@ const ELEVATOR_X = 507
|
||||
const ELEVATOR_W = 108
|
||||
|
||||
const FLOOR_SLOTS = [
|
||||
{ y: 234, h: 179 },
|
||||
{ y: 451, h: 186 },
|
||||
{ y: 675, h: 184 },
|
||||
{ y: 896, h: 180 },
|
||||
{ y: 1112, h: 169 }
|
||||
{ y: 234 + HOUSE_Y_OFFSET, h: 179 },
|
||||
{ y: 451 + HOUSE_Y_OFFSET, h: 186 },
|
||||
{ y: 675 + HOUSE_Y_OFFSET, h: 184 },
|
||||
{ y: 896 + HOUSE_Y_OFFSET, h: 180 },
|
||||
{ y: 1112 + HOUSE_Y_OFFSET, h: 169 }
|
||||
]
|
||||
const FLOOR_COUNT = FLOOR_SLOTS.length
|
||||
const SHELL_BEAM_Y = [432, 656, 877, 1094]
|
||||
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 = 1352
|
||||
const STATUS_Y = 1540
|
||||
|
||||
// A true rooftop level above the shell, rather than a tiny room inside the gable.
|
||||
const ROOF_ROOM_BOUNDS = {
|
||||
x: 470,
|
||||
y: 72,
|
||||
width: 182,
|
||||
height: 132
|
||||
x: 410,
|
||||
y: 18,
|
||||
width: 302,
|
||||
height: 126
|
||||
}
|
||||
|
||||
const ROOF_LIFT_STOP_Y = ROOF_ROOM_BOUNDS.y + Math.round(ROOF_ROOM_BOUNDS.height * 0.84)
|
||||
const ELEVATOR_SHAFT_TOP = ROOF_LIFT_STOP_Y - 48
|
||||
|
||||
const ELEVATOR_CAR_W = 82
|
||||
const ELEVATOR_CAR_H = 90
|
||||
const ELEVATOR_OPENING_W = 78
|
||||
@ -193,9 +199,9 @@ function makeRoofRoom() {
|
||||
width,
|
||||
height,
|
||||
walkBand: {
|
||||
minY: y + Math.round(height * 0.70),
|
||||
minY: y + Math.round(height * 0.72),
|
||||
maxY: y + height - 8,
|
||||
homeY: y + Math.round(height * 0.84)
|
||||
homeY: ROOF_LIFT_STOP_Y
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +222,7 @@ const ROOMS = [
|
||||
const ROOM_BY_ID = new Map(ROOMS.map((room) => [room.id, room]))
|
||||
|
||||
function elevatorStopY(room) {
|
||||
if (room.isRoof) return room.walkBand.homeY
|
||||
if (room.isRoof) return ROOF_LIFT_STOP_Y
|
||||
return room.y + Math.round(room.height / 2)
|
||||
}
|
||||
|
||||
@ -259,9 +265,14 @@ function cropTexture(scene, sourceKey, key, rect) {
|
||||
}
|
||||
|
||||
function buildElevatorSvg() {
|
||||
const shaftHeight = HOUSE_BOTTOM - HOUSE_TOP
|
||||
const openings = FLOOR_SLOTS.map((slot) => {
|
||||
const centerY = slot.y + slot.h / 2 - HOUSE_TOP
|
||||
const shaftHeight = HOUSE_BOTTOM - ELEVATOR_SHAFT_TOP
|
||||
const stopYs = [
|
||||
ROOF_LIFT_STOP_Y,
|
||||
...FLOOR_SLOTS.map((slot) => slot.y + slot.h / 2)
|
||||
]
|
||||
|
||||
const openings = stopYs.map((stopY) => {
|
||||
const centerY = stopY - ELEVATOR_SHAFT_TOP
|
||||
const y = centerY - ELEVATOR_OPENING_H / 2
|
||||
|
||||
return `
|
||||
@ -440,7 +451,12 @@ class HouseScene extends Phaser.Scene {
|
||||
const graphics = this.add.graphics().setDepth(0)
|
||||
|
||||
graphics.fillStyle(0xfffbfd, 1)
|
||||
graphics.fillRect(36, 220, 1050, HOUSE_BOTTOM - 220)
|
||||
graphics.fillRect(
|
||||
36,
|
||||
220 + HOUSE_Y_OFFSET,
|
||||
1050,
|
||||
HOUSE_BOTTOM - (220 + HOUSE_Y_OFFSET)
|
||||
)
|
||||
|
||||
for (const room of ROOMS) {
|
||||
if (room.isRoof) continue
|
||||
@ -587,20 +603,20 @@ class HouseScene extends Phaser.Scene {
|
||||
|
||||
drawRoofRoom() {
|
||||
const room = ROOM_BY_ID.get('roof-garden')
|
||||
const graphics = this.add.graphics().setDepth(9)
|
||||
const graphics = this.add.graphics().setDepth(30)
|
||||
|
||||
const inset = 7
|
||||
const backInset = 28
|
||||
const wallTop = room.y + 8
|
||||
const inset = 8
|
||||
const backInset = 42
|
||||
const wallTop = room.y + 7
|
||||
const backTop = room.y + 18
|
||||
const horizonY = room.y + Math.round(room.height * 0.70)
|
||||
const bottomY = room.y + room.height - 7
|
||||
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 rooftop garden: sky backdrop and a small perspective turf area.
|
||||
// Open-air sky panel and rooftop turf deck.
|
||||
graphics.fillStyle(0xcfefff, 1)
|
||||
graphics.fillRoundedRect(room.x, room.y, room.width, room.height, 18)
|
||||
|
||||
@ -615,61 +631,65 @@ class HouseScene extends Phaser.Scene {
|
||||
new Phaser.Geom.Point(left, bottomY)
|
||||
], true)
|
||||
|
||||
// Garden edging / planter boxes.
|
||||
graphics.fillStyle(0xf5d2a5, 1)
|
||||
graphics.fillRoundedRect(backLeft + 8, horizonY - 18, 38, 16, 5)
|
||||
graphics.fillRoundedRect(backRight - 46, horizonY - 18, 38, 16, 5)
|
||||
// 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)
|
||||
|
||||
// Planters.
|
||||
graphics.fillStyle(0xf3c797, 1)
|
||||
graphics.fillRoundedRect(left + 16, horizonY - 20, 58, 18, 5)
|
||||
graphics.fillRoundedRect(right - 74, horizonY - 20, 58, 18, 5)
|
||||
|
||||
// Simple flowers and leafy plants rendered in Phaser so the roof remains responsive.
|
||||
const plantDepth = 12
|
||||
const flowers = [
|
||||
{ x: backLeft + 26, y: horizonY - 24, color: '#ff7fa9' },
|
||||
{ x: backLeft + 37, y: horizonY - 30, color: '#ffd86a' },
|
||||
{ x: backRight - 30, y: horizonY - 25, color: '#b78cff' },
|
||||
{ x: backRight - 18, y: horizonY - 31, color: '#ff8f7e' }
|
||||
{ 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' }
|
||||
]
|
||||
|
||||
flowers.forEach((flower) => {
|
||||
this.add.text(flower.x, flower.y, '✿', {
|
||||
fontFamily: 'Arial',
|
||||
fontSize: '18px',
|
||||
fontSize: '20px',
|
||||
color: flower.color
|
||||
}).setOrigin(0.5).setDepth(plantDepth)
|
||||
}).setOrigin(0.5).setDepth(32)
|
||||
})
|
||||
|
||||
// Small garden bench in the middle.
|
||||
// Bench, offset left so the lift exit on the right remains clear.
|
||||
graphics.fillStyle(0xe5b982, 1)
|
||||
graphics.fillRoundedRect(room.x + room.width / 2 - 24, horizonY - 10, 48, 8, 4)
|
||||
graphics.fillRect(room.x + room.width / 2 - 20, horizonY - 3, 5, 14)
|
||||
graphics.fillRect(room.x + room.width / 2 + 15, horizonY - 3, 5, 14)
|
||||
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)
|
||||
|
||||
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 + 10, room.y + 8, 'Rooftop Garden', {
|
||||
this.add.text(room.x + 12, room.y + 9, 'Rooftop Garden', {
|
||||
fontFamily: 'Arial Rounded MT Bold, ui-rounded, sans-serif',
|
||||
fontSize: '13px',
|
||||
fontSize: '15px',
|
||||
color: '#5f7552',
|
||||
fontStyle: 'bold',
|
||||
backgroundColor: 'rgba(255,255,255,0.84)',
|
||||
padding: { x: 5, y: 2 }
|
||||
}).setDepth(13)
|
||||
backgroundColor: 'rgba(255,255,255,0.86)',
|
||||
padding: { x: 6, y: 3 }
|
||||
}).setDepth(33)
|
||||
}
|
||||
|
||||
buildHouseShell() {
|
||||
const shellDepth = 7
|
||||
const towerDepth = 8
|
||||
|
||||
this.add.image(WIDTH / 2, 0, 'shell-roof')
|
||||
this.add.image(WIDTH / 2, HOUSE_Y_OFFSET, 'shell-roof')
|
||||
.setOrigin(0.5, 0)
|
||||
.setDisplaySize(1122, 242)
|
||||
.setDepth(shellDepth)
|
||||
|
||||
this.add.image(TOWER_CENTER_X, 0, 'shell-tower')
|
||||
this.add.image(TOWER_CENTER_X, HOUSE_Y_OFFSET, 'shell-tower')
|
||||
.setOrigin(0.5, 0)
|
||||
.setDisplaySize(TOWER_W, HEIGHT)
|
||||
.setDisplaySize(TOWER_W, SHELL_HEIGHT)
|
||||
.setDepth(towerDepth)
|
||||
|
||||
const leftOuterX = 60.5
|
||||
@ -710,25 +730,36 @@ class HouseScene extends Phaser.Scene {
|
||||
.setDepth(shellDepth + 2)
|
||||
}
|
||||
|
||||
this.add.image(0, 1240, 'shell-foundation-left')
|
||||
this.add.image(0, 1240 + HOUSE_Y_OFFSET, 'shell-foundation-left')
|
||||
.setOrigin(0, 0)
|
||||
.setDisplaySize(462, 162)
|
||||
.setDepth(shellDepth + 1)
|
||||
|
||||
this.add.image(660, 1240, 'shell-foundation-right')
|
||||
this.add.image(660, 1240 + HOUSE_Y_OFFSET, 'shell-foundation-right')
|
||||
.setOrigin(0, 0)
|
||||
.setDisplaySize(462, 162)
|
||||
.setDepth(shellDepth + 1)
|
||||
}
|
||||
|
||||
buildElevator() {
|
||||
const shaftHeight = HOUSE_BOTTOM - HOUSE_TOP
|
||||
const shaftHeight = HOUSE_BOTTOM - ELEVATOR_SHAFT_TOP
|
||||
|
||||
this.add.image(ELEVATOR_X + ELEVATOR_W / 2, HOUSE_TOP, 'elevator-shaft')
|
||||
this.add.image(ELEVATOR_X + ELEVATOR_W / 2, ELEVATOR_SHAFT_TOP, 'elevator-shaft')
|
||||
.setOrigin(0.5, 0)
|
||||
.setDisplaySize(ELEVATOR_W, shaftHeight)
|
||||
.setDepth(20)
|
||||
|
||||
this.add.rectangle(
|
||||
ELEVATOR_X + ELEVATOR_W / 2,
|
||||
ROOF_LIFT_STOP_Y,
|
||||
ELEVATOR_W + 18,
|
||||
ELEVATOR_OPENING_H + 20,
|
||||
0xfff4f8,
|
||||
0.96
|
||||
)
|
||||
.setStrokeStyle(4, 0xd8a2b9)
|
||||
.setDepth(18)
|
||||
|
||||
const currentRoom = this.currentRoom()
|
||||
const stopY = elevatorStopY(currentRoom)
|
||||
const cx = ELEVATOR_X + ELEVATOR_W / 2
|
||||
@ -817,7 +848,7 @@ class HouseScene extends Phaser.Scene {
|
||||
room.width,
|
||||
room.height
|
||||
)
|
||||
.setDepth(3)
|
||||
.setDepth(room.isRoof ? 40 : 3)
|
||||
.setData('roomId', room.id)
|
||||
.setInteractive()
|
||||
|
||||
@ -1358,7 +1389,7 @@ const game = new Phaser.Game({
|
||||
})
|
||||
|
||||
window.__DOLLHOUSE__ = {
|
||||
version: '0.9.1',
|
||||
version: '0.10.0',
|
||||
game,
|
||||
async resetAll() {
|
||||
await clearGameState()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user