Fix frozen video feed on window reopen and add construct SFX

- Use `video.resume()` instead of `video.play()` in Build, Map, Quest,
  and Research windows: Phaser v4's `play()` is a no-op after `pause()`
  because the `_playCalled` flag stays true, leaving the feed frozen
  after close → reopen. `resume()` handles both first open and re-open.
- Play the 'construct' SFX when the planet HUD lines start their
  scramble-decode animation in SurfaceScene.
This commit is contained in:
Brian Fertig 2026-09-08 10:32:46 -06:00
parent 9b7bf334e4
commit ec68fa142c
5 changed files with 25 additions and 4 deletions

View File

@ -446,6 +446,7 @@ export class SurfaceScene extends Phaser.Scene {
if (!this.hudLines) return;
if (this.hudT0 === null) {
this.hudT0 = time;
this.playSfx('construct'); // the planet info starts typing in (data/sfx.json → construct)
for (const ln of this.hudLines) ln.dec = new ScrambleDecode(ln.value, time + ln.delay, ln.dur);
}
let done = true;

View File

@ -1233,7 +1233,12 @@ export class BuildWindow extends Phaser.GameObjects.Container {
this._paintAll(this.activeCat);
this._paintStatusStrip();
this.video?.play?.();
// resume() not play(): v4's play() is a no-op after pause() (its
// _playCalled flag stays true, so the native play() is never
// re-issued) — the feed would stay frozen after close → reopen.
// resume() handles both a first open (delegates to play()) and a
// re-open of a paused clip.
this.video?.resume?.();
this.sfx('ui_window');
this._startReveal();

View File

@ -2171,7 +2171,12 @@ export class MapWindow extends Phaser.GameObjects.Container {
if (this.openState === 'open' || this.openState === 'opening') return;
this.openState = 'opening';
this.setAlpha(0);
this.video?.play?.();
// resume() not play(): v4's play() is a no-op after pause() (its
// _playCalled flag stays true, so the native play() is never
// re-issued) — the feed would stay frozen after close → reopen.
// resume() handles both a first open (delegates to play()) and a
// re-open of a paused clip.
this.video?.resume?.();
this.sfx('ui_window');
const now = this.scene.time.now;
this._startReveal(now);

View File

@ -1065,7 +1065,12 @@ export class QuestWindow extends Phaser.GameObjects.Container {
if (this.openState === 'open' || this.openState === 'opening') return;
this.openState = 'opening';
this.setAlpha(0);
this.video?.play?.();
// resume() not play(): v4's play() is a no-op after pause() (its
// _playCalled flag stays true, so the native play() is never
// re-issued) — the feed would stay frozen after close → reopen.
// resume() handles both a first open (delegates to play()) and a
// re-open of a paused clip.
this.video?.resume?.();
this.sfx('ui_window');
this._startReveal(this.scene.time.now);
}

View File

@ -1269,7 +1269,12 @@ export class ResearchWindow extends Phaser.GameObjects.Container {
this._paintAll(this.activeCat);
this._paintStatusStrip();
this.video?.play?.();
// resume() not play(): v4's play() is a no-op after pause() (its
// _playCalled flag stays true, so the native play() is never
// re-issued) — the feed would stay frozen after close → reopen.
// resume() handles both a first open (delegates to play()) and a
// re-open of a paused clip.
this.video?.resume?.();
this.sfx('ui_window');
this._startReveal();
}