refactor GoFishGame: align portrait/chip positions and add status text background

This commit is contained in:
Brian Fertig 2026-05-18 22:32:19 -06:00
parent d46de05b48
commit dcb8503219
1 changed files with 53 additions and 19 deletions

View File

@ -37,50 +37,70 @@ const SLOTS_USED = {
function slotLayout(slot) {
switch (slot) {
case 'bottom':
case 'bottom': {
// chip bottom edge = bchipY + 22; portrait bottom aligns with chip bottom
// portrait left of chip with 12px gap
const bchipY = GAME_HEIGHT - 100 - CARD_H / 2 - 30;
const bpr = 56, bpx = CX - 90 - 12 - bpr, bpy = bchipY + 22 - bpr;
return {
handCenter: { x: CX, y: GAME_HEIGHT - 100 },
handAxis: 'x',
handFaceUp: true,
portrait: { x: 220, y: GAME_HEIGHT - 130, r: 56 },
nameLabel: { x: 220, y: GAME_HEIGHT - 60 },
chip: { x: CX, y: GAME_HEIGHT - 100 - CARD_H / 2 - 30 },
portrait: { x: bpx, y: bpy, r: bpr },
nameLabel: { x: bpx, y: bpy - bpr - 14 },
chip: { x: CX, y: bchipY },
chipRotation: 0,
rotateCards: 0,
};
case 'top':
}
case 'top': {
// chip top edge = tchipY - 22; portrait top aligns with chip top
// portrait left of chip with 12px gap
const tchipY = 110 + CARD_H / 2 + 30;
const tpr = 50, tpx = CX - 90 - 12 - tpr, tpy = tchipY - 22 + tpr;
return {
handCenter: { x: CX, y: 110 },
handAxis: 'x',
handFaceUp: false,
portrait: { x: 220, y: 130, r: 50 },
nameLabel: { x: 220, y: 200 },
chip: { x: CX, y: 110 + CARD_H / 2 + 30 },
portrait: { x: tpx, y: tpy, r: tpr },
nameLabel: { x: tpx, y: tpy + tpr + 14 },
chip: { x: CX, y: tchipY },
chipRotation: 0,
rotateCards: 180,
};
case 'left':
}
case 'left': {
// chip at (205, CY) rotated — extends ±90 in y, ±22 in x
// portrait left edge aligned with chip left edge (chipX - 22)
const lchipX = 110 + CARD_H / 2 + 10 + 22;
const lpr = 50, lpx = lchipX - 22 + lpr, lpy = CY - 90 - 12 - lpr;
return {
handCenter: { x: 110, y: CY },
handAxis: 'y',
handFaceUp: false,
portrait: { x: 130, y: 220, r: 50 },
nameLabel: { x: 130, y: 290 },
chip: { x: 110 + CARD_H / 2 + 10 + 22, y: CY },
portrait: { x: lpx, y: lpy, r: lpr },
nameLabel: { x: lpx, y: lpy - lpr - 14 },
chip: { x: lchipX, y: CY },
chipRotation: Math.PI / 2,
rotateCards: 90,
};
case 'right':
}
case 'right': {
// chip at (1715, CY) rotated — extends ±90 in y, ±22 in x
// portrait right edge aligned with chip right edge (chipX + 22)
const rchipX = GAME_WIDTH - 110 - CARD_H / 2 - 10 - 22;
const rpr = 50, rpx = rchipX + 22 - rpr, rpy = CY - 90 - 12 - rpr;
return {
handCenter: { x: GAME_WIDTH - 110, y: CY },
handAxis: 'y',
handFaceUp: false,
portrait: { x: GAME_WIDTH - 130, y: 220, r: 50 },
nameLabel: { x: GAME_WIDTH - 130, y: 290 },
chip: { x: GAME_WIDTH - 110 - CARD_H / 2 - 10 - 22, y: CY },
portrait: { x: rpx, y: rpy, r: rpr },
nameLabel: { x: rpx, y: rpy - rpr - 14 },
chip: { x: rchipX, y: CY },
chipRotation: -Math.PI / 2,
rotateCards: 270,
};
}
default:
throw new Error(`Unknown slot: ${slot}`);
}
@ -222,9 +242,12 @@ export default class GoFishGame extends Phaser.Scene {
}
buildHUD() {
this.statusText = this.add.text(CX, GAME_HEIGHT - 230, '', {
fontFamily: 'Righteous', fontSize: '24px', color: COLORS.textHex, align: 'center',
}).setOrigin(0.5).setDepth(D.ui);
// Sit just right of bottom portrait (right edge = CX - 90) and just above chip top (bchipY - 22).
const bchipY = GAME_HEIGHT - 100 - CARD_H / 2 - 30;
this.statusBg = this.add.graphics().setDepth(D.ui - 1);
this.statusText = this.add.text(CX - 90, bchipY - 22 - 14, '', {
fontFamily: 'Righteous', fontSize: '24px', color: COLORS.textHex, align: 'left',
}).setOrigin(0, 1).setDepth(D.ui);
new Button(this, 80, GAME_HEIGHT - 30, 'Leave', () => this.scene.start('GameMenu'), {
variant: 'ghost', width: 120, height: 40, fontSize: 18,
@ -427,6 +450,7 @@ export default class GoFishGame extends Phaser.Scene {
updateStatus() {
if (this.gameOver) {
this.statusText.setText('');
this.statusBg.setVisible(false);
return;
}
if (this.isLocalTurn()) {
@ -438,6 +462,16 @@ export default class GoFishGame extends Phaser.Scene {
} else {
this.statusText.setText(`${this.opponentName(this.gs.currentPlayer)} is thinking…`);
}
this.refreshStatusBg();
}
refreshStatusBg() {
const t = this.statusText;
const pad = 8;
this.statusBg.clear();
this.statusBg.fillStyle(0x000000, 0.55);
this.statusBg.fillRoundedRect(t.x - pad, t.y - t.height - pad, t.width + pad * 2, t.height + pad * 2, 6);
this.statusBg.setVisible(true);
}
showBanner(text) {