diff --git a/js/ui/BuildWindow.js b/js/ui/BuildWindow.js index 7609809..1ebf4ec 100644 --- a/js/ui/BuildWindow.js +++ b/js/ui/BuildWindow.js @@ -298,12 +298,15 @@ export class BuildWindow extends Phaser.GameObjects.Container { const cy = rect.y + titleH / 2 - 2; this.closeBtn = { x: cx, y: cy, w: cw, h: cw, hover: false }; this.closeG = G(2); - this.closeTxt = T(cx, cy - 5, '✕', { + this.closeTxt = T(cx, cy + 1, '✕', { fontFamily: BODY, fontSize: '15px', color: toCss(C.neon2), align: 'center', }, 2); + // Text's default origin is (0,0) — without this the ✕ anchors its + // top-left at the plate centre and sits right-of-centre. + this.closeTxt.setOrigin(0.5, 0.5); const closeRect = new Phaser.Geom.Rectangle(cx - cw / 2, cy - cw / 2, cw, cw); this.closeG.setInteractive({ useHandCursor: true, @@ -915,7 +918,9 @@ export class BuildWindow extends Phaser.GameObjects.Container { }) .setScrollFactor(0); cont.add(this.dCost); - const btnW = 152; + // 190: the widest label is "IN PROGRESS 88%" (~166 px at 13px/ls-3) — + // 152 let it bleed past the plate edges. + const btnW = 190; const wrapW = Math.max(120, rightX + rightW - 12 - btnW - 18 - tx); this.dDesc = s .text(tx, detailY + 80, '', { @@ -944,6 +949,7 @@ export class BuildWindow extends Phaser.GameObjects.Container { letterSpacing: 3, align: 'center', }) + .setOrigin(0.5, 0) // centre on the plate — text's default origin is (0,0) .setScrollFactor(0); const bar = s.graphics().setScrollFactor(0); cont.add([g, label, bar]); @@ -1250,8 +1256,12 @@ export class BuildWindow extends Phaser.GameObjects.Container { }); } + // 'closing' counts as open: the close button flips openState in the + // SAME input pass, before the scene's pointerdown guard runs — while + // the window is still on screen (fading out) it must keep owning the + // click, or the close tap leaks through as a world click. get isOpen() { - return this.openState === 'open' || this.openState === 'opening'; + return this.openState === 'open' || this.openState === 'opening' || this.openState === 'closing'; } /** Repaint everything from state (after a build starts / completes). */ diff --git a/js/ui/ResearchWindow.js b/js/ui/ResearchWindow.js index 3a55786..b7431f3 100644 --- a/js/ui/ResearchWindow.js +++ b/js/ui/ResearchWindow.js @@ -271,12 +271,15 @@ export class ResearchWindow extends Phaser.GameObjects.Container { const cy = rect.y + titleH / 2 - 2; this.closeBtn = { x: cx, y: cy, w: cw, h: cw, hover: false }; this.closeG = G(2); - this.closeTxt = T(cx, cy - 5, '✕', { + this.closeTxt = T(cx, cy + 1, '✕', { fontFamily: BODY, fontSize: '15px', color: toCss(C.neon2), align: 'center', }, 2); + // Text's default origin is (0,0) — without this the ✕ anchors its + // top-left at the plate centre and sits right-of-centre. + this.closeTxt.setOrigin(0.5, 0.5); // v4: setInteractive takes a config object — a bare shape (or the // 4-arg Phaser-3 form) leaves input.hitAreaCallback unset and // pointWithinHitArea throws on the first pointer move over it. @@ -835,7 +838,9 @@ export class ResearchWindow extends Phaser.GameObjects.Container { }) .setScrollFactor(0); cont.add(this.dUnlocks); - const btnW = 152; + // 190: the widest label is "IN PROGRESS 88%" (~166 px at 13px/ls-3) — + // 152 let it bleed past the plate edges. + const btnW = 190; const wrapW = Math.max(120, rightX + rightW - 12 - btnW - 18 - tx); this.dDesc = s .text(tx, detailY + 76, '', { @@ -864,6 +869,7 @@ export class ResearchWindow extends Phaser.GameObjects.Container { letterSpacing: 3, align: 'center', }) + .setOrigin(0.5, 0) // centre on the plate — text's default origin is (0,0) .setScrollFactor(0); const bar = s.graphics().setScrollFactor(0); // v4 Container.add(child, index) — multi-add is the ARRAY form. @@ -1264,8 +1270,13 @@ export class ResearchWindow extends Phaser.GameObjects.Container { }); } + // 'closing' counts as open: the close button flips openState in the + // SAME input pass, before the scene's pointerdown guard runs — while + // the window is still on screen (fading out) it must keep owning the + // click, or the close tap leaks through as a world click (the ship + // flies at the ✕). get isOpen() { - return this.openState === 'open' || this.openState === 'opening'; + return this.openState === 'open' || this.openState === 'opening' || this.openState === 'closing'; } /** Repaint everything from state (after research starts / completes). */