Fix jigsaw camera bounds and piece tray to avoid overlapping the HUD

- Offset main camera scroll/zoom bounds by HUD_H so the play field
  never slides beneath the fixed top bar
- Shift the scattered-piece tray down by HUD_H to keep pieces clear of
  the target image and HUD
- Assign board panel, frame, and reference image to the main camera only
  so the fixed HUD camera doesn't draw their corners into the screen
This commit is contained in:
Brian Fertig 2026-08-30 19:03:28 -06:00
parent dca1cbef4d
commit b6299234cf
1 changed files with 9 additions and 4 deletions

View File

@ -75,7 +75,7 @@ export default class JigsawGame extends Phaser.Scene {
this.buildMenu(); this.buildMenu();
this.bindInput(); this.bindInput();
this.cameras.main.setBounds(0, 0, WORLD_W, WORLD_H); this.cameras.main.setBounds(0, HUD_H, WORLD_W, WORLD_H - HUD_H);
this.cameras.main.setZoom(1); this.cameras.main.setZoom(1);
this.cameras.main.setScroll(0, 0); this.cameras.main.setScroll(0, 0);
@ -385,6 +385,9 @@ export default class JigsawGame extends Phaser.Scene {
boardFrame.strokeRect(BOARD.x, BOARD.y, BOARD.size, BOARD.size); boardFrame.strokeRect(BOARD.x, BOARD.y, BOARD.size, BOARD.size);
this.boardPanel = panel; this.boardPanel = panel;
this.boardFrame = boardFrame; this.boardFrame = boardFrame;
// Keep board on the main camera only (the fixed HUD camera would draw its
// top-left corner into the lower-right of the screen).
if (this.hudCam) { panel.cameraFilter = this.hudCam.id; boardFrame.cameraFilter = this.hudCam.id; }
const srcImg = _imgCache[item.path]; const srcImg = _imgCache[item.path];
// Build the faint reference into a canvas texture (cover-cropped square), // Build the faint reference into a canvas texture (cover-cropped square),
@ -403,6 +406,7 @@ export default class JigsawGame extends Phaser.Scene {
if (this.textures.exists('jigsaw-ref')) this.textures.remove('jigsaw-ref'); if (this.textures.exists('jigsaw-ref')) this.textures.remove('jigsaw-ref');
this.textures.addCanvas('jigsaw-ref', rcv); this.textures.addCanvas('jigsaw-ref', rcv);
this.refImage = this.add.image(bcx, bcy, 'jigsaw-ref').setDisplaySize(BOARD.size, BOARD.size).setAlpha(0.16).setDepth(3); this.refImage = this.add.image(bcx, bcy, 'jigsaw-ref').setDisplaySize(BOARD.size, BOARD.size).setAlpha(0.16).setDepth(3);
if (this.hudCam) this.refImage.cameraFilter = this.hudCam.id; // main camera only
// Faint full-picture reference: keep on Easy/Medium, hide on Hard/Legendary. // Faint full-picture reference: keep on Easy/Medium, hide on Hard/Legendary.
this.refImage.setVisible(this.difficulty !== 'hard' && this.difficulty !== 'legendary'); this.refImage.setVisible(this.difficulty !== 'hard' && this.difficulty !== 'legendary');
@ -500,7 +504,7 @@ export default class JigsawGame extends Phaser.Scene {
// (pieces must not scatter on top of the target image or they'd be // (pieces must not scatter on top of the target image or they'd be
// indistinguishable from placed pieces). The HUD lives in viewport space, // indistinguishable from placed pieces). The HUD lives in viewport space,
// so it doesn't reserve any of the world. // so it doesn't reserve any of the world.
const tray = { x: 40, y: 40, w: WORLD_W - 80, h: WORLD_H - 80 }; const tray = { x: 40, y: HUD_H + 40, w: WORLD_W - 80, h: WORLD_H - HUD_H - 80 };
const boardBox = { x0: BOARD.x - 6, y0: BOARD.y - 6, x1: BOARD.x + BOARD.size + 6, y1: BOARD.y + BOARD.size + 6 }; const boardBox = { x0: BOARD.x - 6, y0: BOARD.y - 6, x1: BOARD.x + BOARD.size + 6, y1: BOARD.y + BOARD.size + 6 };
const grabR = this.cell * GRAB_FRAC; const grabR = this.cell * GRAB_FRAC;
// We guarantee a comfortable minimum centre-gap so no two pieces steal each // We guarantee a comfortable minimum centre-gap so no two pieces steal each
@ -712,7 +716,8 @@ export default class JigsawGame extends Phaser.Scene {
const cam = this.cameras.main; const cam = this.cameras.main;
const vw = GAME_WIDTH / cam.zoom, vh = GAME_HEIGHT / cam.zoom; const vw = GAME_WIDTH / cam.zoom, vh = GAME_HEIGHT / cam.zoom;
cam.scrollX = Phaser.Math.Clamp(cam.scrollX, 0, Math.max(0, WORLD_W - vw)); cam.scrollX = Phaser.Math.Clamp(cam.scrollX, 0, Math.max(0, WORLD_W - vw));
cam.scrollY = Phaser.Math.Clamp(cam.scrollY, 0, Math.max(0, WORLD_H - vh)); // Top bound = HUD_H so the play field never slides under the fixed top bar.
cam.scrollY = Phaser.Math.Clamp(cam.scrollY, HUD_H, Math.max(HUD_H, WORLD_H - vh));
} }
// Zoom about the point (cx, cy) in canvas space: the world point under that // Zoom about the point (cx, cy) in canvas space: the world point under that
@ -741,7 +746,7 @@ export default class JigsawGame extends Phaser.Scene {
resetToCanvas() { resetToCanvas() {
const cam = this.cameras.main; const cam = this.cameras.main;
cam.setZoom(1); cam.setZoom(1);
cam.setScroll(0, 0); cam.setScroll(0, HUD_H); // top bound so the field never sits under the HUD
} }
setZoomTo(z) { setZoomTo(z) {