Queue player hits outside physics overlap

This commit is contained in:
Admin 2026-09-18 00:13:06 +00:00
parent 2f837d15e6
commit a1f675194a

View File

@ -43,6 +43,7 @@ class GameScene extends Phaser.Scene {
this.gameState = 'playing'; this.gameState = 'playing';
this.lastPlayerShot = 0; this.lastPlayerShot = 0;
this.lastPlayerHitAt = -Infinity; this.lastPlayerHitAt = -Infinity;
this.pendingPlayerHits = [];
this.wave = 1; this.wave = 1;
this.defeated = 0; this.defeated = 0;
} }
@ -305,6 +306,12 @@ class GameScene extends Phaser.Scene {
return; return;
} }
this.processPlayerHits();
if (this.gameState !== 'playing') {
this.drawHud();
return;
}
this.updatePlayer(dt, deltaMs); this.updatePlayer(dt, deltaMs);
this.updatePirates(dt); this.updatePirates(dt);
this.updateProjectiles(); this.updateProjectiles();
@ -430,21 +437,37 @@ class GameScene extends Phaser.Scene {
hitPlayer(shot) { hitPlayer(shot) {
if (!shot?.active || this.gameState !== 'playing') return; if (!shot?.active || this.gameState !== 'playing') return;
if (shot.getData('playerHitQueued')) return;
const rawDamage = Number(shot.getData('damage')); const rawDamage = Number(shot.getData('damage'));
const damage = clamp(Number.isFinite(rawDamage) ? rawDamage : PIRATE_SHOT_DAMAGE, 1, 25); const damage = clamp(Number.isFinite(rawDamage) ? rawDamage : PIRATE_SHOT_DAMAGE, 1, 25);
// Keep enemy -> player collision deliberately side-effect-light until the // The Arcade overlap callback only records the collision. Object removal
// freeze is isolated. Projectile removal and hull mutation only. // and hull mutation happen from the scene update after the physics step.
shot.destroy(); shot.setData('playerHitQueued', true);
this.pendingPlayerHits.push({ shot, damage });
}
if (this.time.now - this.lastPlayerHitAt < PLAYER_HIT_COOLDOWN_MS) return; processPlayerHits() {
this.lastPlayerHitAt = this.time.now; if (!this.pendingPlayerHits.length || this.gameState !== 'playing') return;
const currentHull = Number.isFinite(this.playerHull) ? this.playerHull : PLAYER_MAX_HULL; const hits = this.pendingPlayerHits;
this.playerHull = Math.max(0, currentHull - damage); this.pendingPlayerHits = [];
if (this.playerHull <= 0) this.finishGame(); for (const { shot, damage } of hits) {
if (shot?.active) shot.destroy();
if (this.time.now - this.lastPlayerHitAt < PLAYER_HIT_COOLDOWN_MS) continue;
this.lastPlayerHitAt = this.time.now;
const currentHull = Number.isFinite(this.playerHull) ? this.playerHull : PLAYER_MAX_HULL;
this.playerHull = Math.max(0, currentHull - damage);
if (this.playerHull <= 0) {
this.finishGame();
break;
}
}
} }
spawnExplosion(x, y, scale = 1) { spawnExplosion(x, y, scale = 1) {