refactor(phase10): manage staging buttons via dedicated lifecycle methods
- Extract button creation and destruction into `_createStagingButtons` and `_destroyStagingButtons`. - Ensure buttons are properly destroyed when staging is cleared, submitted, or when turn conditions change. - Prevent memory leaks and stale UI state by centralizing button lifecycle management. - Add piece click sound effect in Backgammon on landing.
This commit is contained in:
parent
208645246c
commit
238c744e93
|
|
@ -802,7 +802,10 @@ export default class BackgammonGame extends Phaser.Scene {
|
||||||
container.x = to.x;
|
container.x = to.x;
|
||||||
container.y = to.y;
|
container.y = to.y;
|
||||||
// Squash-and-stretch on landing
|
// Squash-and-stretch on landing
|
||||||
this.tweens.add({ targets: container, scaleX: 1.3, scaleY: 0.7, duration: 60, yoyo: true, ease: 'Quad.easeOut', onComplete });
|
this.tweens.add({ targets: container, scaleX: 1.3, scaleY: 0.7, duration: 60, yoyo: true, ease: 'Quad.easeOut', onComplete: () => {
|
||||||
|
playSound(this, SFX.PIECE_CLICK);
|
||||||
|
onComplete();
|
||||||
|
}});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
this.dragState = null;
|
this.dragState = null;
|
||||||
this.potentialDrag = null;
|
this.potentialDrag = null;
|
||||||
this.stagingGroups = null;
|
this.stagingGroups = null;
|
||||||
|
this.submitBtn = null;
|
||||||
|
this.clearBtn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
|
@ -761,16 +763,6 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
cx += gw + GROUP_GAP;
|
cx += gw + GROUP_GAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
const btnX = panelX + panelW + 160;
|
|
||||||
const submitBtn = new Button(this, btnX, laidStart.y - 18, 'Submit Phase', () => this.submitStagingLaydown(), {
|
|
||||||
width: 200, height: 44, fontSize: 18,
|
|
||||||
}).setDepth(D.ui);
|
|
||||||
this.transientObjs.push(submitBtn);
|
|
||||||
|
|
||||||
const clearBtn = new Button(this, btnX, laidStart.y + 34, 'Clear', () => this.clearStagingLaydown(), {
|
|
||||||
variant: 'ghost', width: 200, height: 34, fontSize: 14,
|
|
||||||
}).setDepth(D.ui);
|
|
||||||
this.transientObjs.push(clearBtn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
submitStagingLaydown() {
|
submitStagingLaydown() {
|
||||||
|
|
@ -798,6 +790,7 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.stagingGroups = null;
|
this.stagingGroups = null;
|
||||||
|
this._destroyStagingButtons();
|
||||||
this.gs = next;
|
this.gs = next;
|
||||||
this.selectedHandIdx = null;
|
this.selectedHandIdx = null;
|
||||||
this.clearHighlights();
|
this.clearHighlights();
|
||||||
|
|
@ -954,6 +947,7 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
this.matchOver = false;
|
this.matchOver = false;
|
||||||
if (this.dragState) this.endCardDragImmediate();
|
if (this.dragState) this.endCardDragImmediate();
|
||||||
this.stagingGroups = null;
|
this.stagingGroups = null;
|
||||||
|
this._destroyStagingButtons();
|
||||||
this.clearAllCardObjs();
|
this.clearAllCardObjs();
|
||||||
this.clearHighlights();
|
this.clearHighlights();
|
||||||
this.selectedHandIdx = null;
|
this.selectedHandIdx = null;
|
||||||
|
|
@ -1241,6 +1235,7 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
const eligible = this.isLocalTurn() && this.gs.drawnThisTurn && !player.laidDown;
|
const eligible = this.isLocalTurn() && this.gs.drawnThisTurn && !player.laidDown;
|
||||||
if (!eligible) {
|
if (!eligible) {
|
||||||
this.stagingGroups = null;
|
this.stagingGroups = null;
|
||||||
|
this._destroyStagingButtons();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.stagingGroups) {
|
if (!this.stagingGroups) {
|
||||||
|
|
@ -1251,9 +1246,34 @@ export default class Phase10Game extends Phaser.Scene {
|
||||||
count: g.count,
|
count: g.count,
|
||||||
slots: new Array(g.count).fill(null),
|
slots: new Array(g.count).fill(null),
|
||||||
}));
|
}));
|
||||||
|
this._createStagingButtons();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_createStagingButtons() {
|
||||||
|
this._destroyStagingButtons();
|
||||||
|
const { laidStart } = slotLayout('bottom');
|
||||||
|
let totalW = 0;
|
||||||
|
for (let i = 0; i < this.stagingGroups.length; i++) {
|
||||||
|
if (i > 0) totalW += GROUP_GAP;
|
||||||
|
totalW += this.stagingGroups[i].count * (LAIDOWN_CARD_W * 0.75) + (LAIDOWN_CARD_W * 0.25);
|
||||||
|
}
|
||||||
|
const panelX = laidStart.x - 14;
|
||||||
|
const panelW = totalW + 28;
|
||||||
|
const btnX = panelX + panelW + 160;
|
||||||
|
this.submitBtn = new Button(this, btnX, laidStart.y - 18, 'Submit Phase', () => this.submitStagingLaydown(), {
|
||||||
|
width: 200, height: 44, fontSize: 18,
|
||||||
|
}).setDepth(D.ui);
|
||||||
|
this.clearBtn = new Button(this, btnX, laidStart.y + 34, 'Clear', () => this.clearStagingLaydown(), {
|
||||||
|
variant: 'ghost', width: 200, height: 34, fontSize: 14,
|
||||||
|
}).setDepth(D.ui);
|
||||||
|
}
|
||||||
|
|
||||||
|
_destroyStagingButtons() {
|
||||||
|
if (this.submitBtn) { this.submitBtn.destroy(); this.submitBtn = null; }
|
||||||
|
if (this.clearBtn) { this.clearBtn.destroy(); this.clearBtn = null; }
|
||||||
|
}
|
||||||
|
|
||||||
// ── Local input ─────────────────────────────────────────────────────────
|
// ── Local input ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
isLocalTurn() {
|
isLocalTurn() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue