Compare commits
2 Commits
c7f4dc9bbb
...
74d5abd2a1
| Author | SHA1 | Date |
|---|---|---|
|
|
74d5abd2a1 | |
|
|
57230fc1b1 |
|
|
@ -61,9 +61,9 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
).setOrigin(0, 0.5);
|
||||
this.add(this.atkText);
|
||||
|
||||
// Small "ATK" label under the number (tiny, just for clarity)
|
||||
// Small "ATK" label — to the right of the value (assumes up to 2 digits)
|
||||
const atkLabel = this.scene.add.text(
|
||||
-w / 2 + Math.round(5 * scale), topBannerCY + Math.round(bannerH * 0.30),
|
||||
-w / 2 + Math.round(19 * scale), topBannerCY,
|
||||
'ATK',
|
||||
{ fontSize: fs(5.5), color: '#886666' }
|
||||
).setOrigin(0, 0.5);
|
||||
|
|
@ -77,9 +77,9 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
).setOrigin(1, 0.5);
|
||||
this.add(this.armText);
|
||||
|
||||
// Small "ARM" label
|
||||
// Small "ARM" label — to the left of the value (assumes up to 2 digits)
|
||||
const armLabel = this.scene.add.text(
|
||||
w / 2 - Math.round(5 * scale), topBannerCY + Math.round(bannerH * 0.30),
|
||||
w / 2 - Math.round(19 * scale), topBannerCY,
|
||||
'ARM',
|
||||
{ fontSize: fs(5.5), color: '#667799' }
|
||||
).setOrigin(1, 0.5);
|
||||
|
|
@ -144,9 +144,9 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
).setOrigin(0, 0.5);
|
||||
this.add(this.hpText);
|
||||
|
||||
// Small "HP" label
|
||||
// Small "HP" label — to the right of the value (assumes up to 2 digits)
|
||||
const hpLabel = this.scene.add.text(
|
||||
-w / 2 + Math.round(5 * scale), bottomBannerCY + Math.round(bannerH * 0.30),
|
||||
-w / 2 + Math.round(19 * scale), bottomBannerCY,
|
||||
'HP',
|
||||
{ fontSize: fs(5.5), color: '#337755' }
|
||||
).setOrigin(0, 0.5);
|
||||
|
|
@ -160,9 +160,9 @@ export class CardObject extends Phaser.GameObjects.Container {
|
|||
).setOrigin(1, 0.5);
|
||||
this.add(this.dlyText);
|
||||
|
||||
// Small "DLY" label
|
||||
// Small "DLY" label — to the left of the value (assumes up to 2 digits)
|
||||
const dlyLabel = this.scene.add.text(
|
||||
w / 2 - Math.round(5 * scale), bottomBannerCY + Math.round(bannerH * 0.30),
|
||||
w / 2 - Math.round(19 * scale), bottomBannerCY,
|
||||
'DLY',
|
||||
{ fontSize: fs(5.5), color: '#777777' }
|
||||
).setOrigin(1, 0.5);
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
this.isAnimating = false;
|
||||
this._updateLog();
|
||||
this.statusText.setText('Press SPACE or click Next Turn to advance');
|
||||
this._animateInitiativeHandoff();
|
||||
if (this.engine.winner) {
|
||||
this.time.delayedCall(600, () => this._showResult());
|
||||
}
|
||||
|
|
@ -329,24 +330,34 @@ export class BattleScene extends Phaser.Scene {
|
|||
}
|
||||
|
||||
// Update a card's HP bar and stats at the moment of impact, then handle death.
|
||||
// If the defender was already killed via _onAttackReconcile, cardObjects.get() returns
|
||||
// null here and the function exits early — no double-death.
|
||||
_refreshCardAfterAttack(cardData) {
|
||||
if (!cardData) return;
|
||||
const obj = this.cardObjects.get(cardData.instanceId)
|
||||
?? this.commanderObjects?.get(cardData.instanceId);
|
||||
if (!obj) return;
|
||||
obj.refresh(); // updates HP bar + stats text to current values
|
||||
// Commanders never get destroyed — the win-check handles game-over
|
||||
obj.refresh();
|
||||
// Fallback death path for cards killed by counter/rupture without an HP loss animation
|
||||
if (cardData.currentHP <= 0 && !obj.isCommander) {
|
||||
// Explosion sprite centered on the card
|
||||
const explosionSprite = this.add.sprite(obj.x, obj.y, 'attacks')
|
||||
.setDisplaySize(630, 630)
|
||||
.setDepth(23);
|
||||
explosionSprite.play('explosion_anim');
|
||||
explosionSprite.once('animationcomplete', () => { if (explosionSprite.scene) explosionSprite.destroy(); });
|
||||
this._playCardDeath(obj, cardData);
|
||||
}
|
||||
}
|
||||
|
||||
this.cardObjects.delete(cardData.instanceId);
|
||||
this.tweens.killTweensOf(obj);
|
||||
obj.setScale(1).setDepth(0);
|
||||
// Explosion sprite + fade-out for a defeated lane card.
|
||||
_playCardDeath(obj, cardData) {
|
||||
this.cardObjects.delete(cardData.instanceId);
|
||||
|
||||
this.tweens.killTweensOf(obj);
|
||||
obj.setScale(1).setDepth(0);
|
||||
|
||||
const explosionSprite = this.add.sprite(obj.x, obj.y, 'attacks')
|
||||
.setDisplaySize(630, 630)
|
||||
.setDepth(23);
|
||||
explosionSprite.play('explosion_anim');
|
||||
explosionSprite.once('animationcomplete', () => {
|
||||
if (explosionSprite.scene) explosionSprite.destroy();
|
||||
if (!obj.scene) return;
|
||||
this.tweens.add({
|
||||
targets: obj,
|
||||
scaleX: 1.25, scaleY: 1.25,
|
||||
|
|
@ -355,7 +366,7 @@ export class BattleScene extends Phaser.Scene {
|
|||
ease: 'Power2',
|
||||
onComplete: () => { if (obj.scene) obj.destroy(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Animate a card appearing on the field (scale from 0 with overshoot)
|
||||
|
|
@ -568,9 +579,13 @@ export class BattleScene extends Phaser.Scene {
|
|||
const defenderObj = _lookup(event.defender?.instanceId);
|
||||
const attackerObj = _lookup(event.attacker?.instanceId);
|
||||
|
||||
// HP loss animation on defender
|
||||
// HP loss animation on defender; on completion, trigger death if HP reached zero
|
||||
if (defenderObj?.scene && event.damage > 0) {
|
||||
defenderObj.animateHPLoss(event.damage);
|
||||
defenderObj.animateHPLoss(event.damage, () => {
|
||||
if (event.defender.currentHP <= 0 && !defenderObj.isCommander) {
|
||||
this._playCardDeath(defenderObj, event.defender);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Berserk ATK gain animation on attacker
|
||||
|
|
@ -768,6 +783,18 @@ export class BattleScene extends Phaser.Scene {
|
|||
backBtn.on('pointerdown', () => this.scene.start(this.missionData ? 'CampaignScene' : 'MainMenuScene'));
|
||||
}
|
||||
|
||||
_animateInitiativeHandoff() {
|
||||
if (!this.initiativeIndicator?.scene) return;
|
||||
// playerGoesFirst still reflects the turn that just ended; next turn is the opposite
|
||||
const targetY = this.playerGoesFirst ? 305 : 715;
|
||||
this.tweens.add({
|
||||
targets: this.initiativeIndicator,
|
||||
y: targetY,
|
||||
duration: 700,
|
||||
ease: 'Power2.inOut'
|
||||
});
|
||||
}
|
||||
|
||||
_updateInitiativeIndicator(playerGoesFirst) {
|
||||
if (this.initiativeIndicator) {
|
||||
this.initiativeIndicator.destroy();
|
||||
|
|
@ -775,10 +802,10 @@ export class BattleScene extends Phaser.Scene {
|
|||
}
|
||||
if (!this.textures.exists('attacksFirst')) return;
|
||||
// Position the indicator to the left of the commander card (commander at x=150, width=240)
|
||||
const indicatorX = 22;
|
||||
const indicatorX = 60;
|
||||
const indicatorY = playerGoesFirst ? 715 : 305;
|
||||
this.initiativeIndicator = this.add.image(indicatorX, indicatorY, 'attacksFirst')
|
||||
.setDisplaySize(44, 44)
|
||||
.setDisplaySize(110, 110)
|
||||
.setDepth(5);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue