feat: enhance card rendering with sprite fallbacks and outline rotation

- Update Phase10Game and SkipBoGame to use sprite textures for card backs when available, falling back to graphics drawing otherwise.
- Add outline rotation to SkipBo stock and discard piles for better visual alignment with card orientation.
This commit is contained in:
Brian Fertig 2026-05-17 10:45:30 -06:00
parent 84b5ada639
commit 7c564ff629
2 changed files with 28 additions and 6 deletions

View File

@ -455,8 +455,17 @@ export default class Phase10Game extends Phaser.Scene {
const g = this.add.graphics(); const g = this.add.graphics();
if (!faceUp) { if (!faceUp) {
this.drawCardBackGfx(g, x, y); if (this.cardBack?.spriteIndex !== undefined && this.textures.exists('cardbacks')) {
container.add(g); g.destroy();
container.add(
this.add.image(0, 0, 'cardbacks', this.cardBack.spriteIndex)
.setDisplaySize(CARD_W, CARD_H)
.setOrigin(0.5)
);
} else {
this.drawCardBackGfx(g, x, y);
container.add(g);
}
return; return;
} }

View File

@ -75,6 +75,7 @@ function slotLayout(slot) {
nameLabel:{ x: 120, y: 1030 }, nameLabel:{ x: 120, y: 1030 },
stockCntPos: { x: 260, y: 880 }, stockCntPos: { x: 260, y: 880 },
rotateCards: 0, rotateCards: 0,
outlineRotation: 0,
}; };
case 'top': case 'top':
return { return {
@ -87,6 +88,7 @@ function slotLayout(slot) {
nameLabel:{ x: 120, y: 210 }, nameLabel:{ x: 120, y: 210 },
stockCntPos: { x: 260, y: 60 }, stockCntPos: { x: 260, y: 60 },
rotateCards: 180, rotateCards: 180,
outlineRotation: 0,
}; };
case 'left': case 'left':
return { return {
@ -99,6 +101,7 @@ function slotLayout(slot) {
nameLabel:{ x: 100, y: 50 }, nameLabel:{ x: 100, y: 50 },
stockCntPos:{ x: 180, y: 260 }, stockCntPos:{ x: 180, y: 260 },
rotateCards: 90, rotateCards: 90,
outlineRotation: 90,
}; };
case 'right': case 'right':
return { return {
@ -111,6 +114,7 @@ function slotLayout(slot) {
nameLabel:{ x: 1820, y: 50 }, nameLabel:{ x: 1820, y: 50 },
stockCntPos:{ x: 1740,y: 260 }, stockCntPos:{ x: 1740,y: 260 },
rotateCards: 270, rotateCards: 270,
outlineRotation: 90,
}; };
default: default:
throw new Error(`Unknown slot: ${slot}`); throw new Error(`Unknown slot: ${slot}`);
@ -197,7 +201,7 @@ export default class SkipBoGame extends Phaser.Scene {
// Stock placeholder // Stock placeholder
const sRect = this.add.rectangle(layout.stock.x, layout.stock.y, CARD_W + 6, CARD_H + 6, 0x000000, 0.35) const sRect = this.add.rectangle(layout.stock.x, layout.stock.y, CARD_W + 6, CARD_H + 6, 0x000000, 0.35)
.setStrokeStyle(2, COLORS.muted).setDepth(D.pile); .setStrokeStyle(2, COLORS.muted).setAngle(layout.outlineRotation).setDepth(D.pile);
// Stock count badge // Stock count badge
const sCnt = this.add.text(layout.stockCntPos.x, layout.stockCntPos.y, '0', { const sCnt = this.add.text(layout.stockCntPos.x, layout.stockCntPos.y, '0', {
fontFamily: '"Julius Sans One"', fontSize: '26px', color: COLORS.accentHex, fontStyle: 'bold', fontFamily: '"Julius Sans One"', fontSize: '26px', color: COLORS.accentHex, fontStyle: 'bold',
@ -215,7 +219,7 @@ export default class SkipBoGame extends Phaser.Scene {
for (let d = 0; d < DISCARD_PILE_COUNT; d++) { for (let d = 0; d < DISCARD_PILE_COUNT; d++) {
const pos = layout.discards[d]; const pos = layout.discards[d];
const r = this.add.rectangle(pos.x, pos.y, CARD_W + 6, CARD_H + 6, 0x000000, 0.25) const r = this.add.rectangle(pos.x, pos.y, CARD_W + 6, CARD_H + 6, 0x000000, 0.25)
.setStrokeStyle(1, COLORS.muted).setDepth(D.pile); .setStrokeStyle(1, COLORS.muted).setAngle(layout.outlineRotation).setDepth(D.pile);
if (seat === 0) { if (seat === 0) {
r.setInteractive({ useHandCursor: true }); r.setInteractive({ useHandCursor: true });
r.on('pointerdown', () => this.onDiscardClick(d)); r.on('pointerdown', () => this.onDiscardClick(d));
@ -320,8 +324,17 @@ export default class SkipBoGame extends Phaser.Scene {
const g = this.add.graphics(); const g = this.add.graphics();
if (!faceUp) { if (!faceUp) {
this.drawCardBackGfx(g, x, y); if (this.cardBack?.spriteIndex !== undefined && this.textures.exists('cardbacks')) {
container.add(g); g.destroy();
container.add(
this.add.image(0, 0, 'cardbacks', this.cardBack.spriteIndex)
.setDisplaySize(CARD_W, CARD_H)
.setOrigin(0.5)
);
} else {
this.drawCardBackGfx(g, x, y);
container.add(g);
}
return; return;
} }