Add pause-aware goal reset timer with proper scene cleanup
- Add 3-second countdown timer after goal that resets the scene - Timer pauses when game is paused, respecting pause state - Freeze all game updates (puck, players, goals) during countdown - Properly reset timer flags in create() to fix post-restart state - Add safety checks in Player and Puck update to handle destroyed entities - Remove player goal deceleration behavior (superseded by scene freeze) - Add destroy() method to Player for proper resource cleanup - Clean up goal event listeners before scene restart 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
ca6a444dec
commit
29885d1992
@ -6,7 +6,6 @@ import {
|
||||
PLAYER_RADIUS_SKATER,
|
||||
SPEED_SCALE_FACTOR,
|
||||
MOVEMENT_STOP_THRESHOLD,
|
||||
GOAL_DECELERATION_RATE,
|
||||
DEBUG,
|
||||
TACKLE_COOLDOWN,
|
||||
TACKLE_FALL_DURATION,
|
||||
@ -97,8 +96,7 @@ export class Player extends Phaser.GameObjects.Container {
|
||||
// Home team (left side) faces right, Away team (right side) faces left
|
||||
this.currentAngle = this.team === 'home' ? 0 : Math.PI;
|
||||
|
||||
// Listen for goal events
|
||||
this.scene.events.on('goal', this.onGoal, this);
|
||||
// Note: Goal events are handled by GameScene (freezes game and resets after 3s)
|
||||
|
||||
// Note: Player must be added to scene via scene.add.existing(player) and scene.physics.add.existing(player)
|
||||
// This is handled by GameScene.addPlayer() method, which also sets up the physics body
|
||||
@ -182,28 +180,13 @@ export class Player extends Phaser.GameObjects.Container {
|
||||
this.targetY = targetY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle goal event
|
||||
*/
|
||||
private onGoal(_data: { team: string; goal: string }) {
|
||||
// Gradually decelerate player after goal
|
||||
const decelerate = () => {
|
||||
this.speedMultiplier *= GOAL_DECELERATION_RATE;
|
||||
|
||||
if (this.speedMultiplier > 0.01) {
|
||||
this.scene.time.delayedCall(50, decelerate);
|
||||
} else {
|
||||
this.speedMultiplier = 0;
|
||||
}
|
||||
};
|
||||
|
||||
decelerate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update player movement each frame
|
||||
*/
|
||||
public update(delta: number) {
|
||||
// Skip update if body doesn't exist (player being destroyed)
|
||||
if (!this.body) return;
|
||||
|
||||
const deltaSeconds = delta / 1000;
|
||||
|
||||
// Check if player is fallen and should stay still
|
||||
@ -466,4 +449,17 @@ export class Player extends Phaser.GameObjects.Container {
|
||||
this.debugDetectionCircle.fillPath();
|
||||
this.debugDetectionCircle.strokePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up resources when player is destroyed
|
||||
*/
|
||||
destroy(fromScene?: boolean) {
|
||||
// Destroy detection sensor
|
||||
if (this.detectionSensor) {
|
||||
this.detectionSensor.destroy();
|
||||
}
|
||||
|
||||
// Call parent destroy
|
||||
super.destroy(fromScene);
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +112,9 @@ export class Puck extends Phaser.GameObjects.Container {
|
||||
* Update puck game coordinates based on physics body position
|
||||
*/
|
||||
public update() {
|
||||
// Skip update if body doesn't exist (puck being destroyed)
|
||||
if (!this.body) return;
|
||||
|
||||
// Use body center position (body.x/y is top-left, need to account for that)
|
||||
const bodyX = this.body.x + this.body.width / 2;
|
||||
const bodyY = this.body.y + this.body.height / 2;
|
||||
|
||||
@ -61,17 +61,28 @@ export class GameScene extends Phaser.Scene {
|
||||
private isPaused: boolean = false;
|
||||
private pauseButton!: Phaser.GameObjects.Text;
|
||||
|
||||
// Goal reset timer
|
||||
private goalResetTimer: number = 0;
|
||||
private isWaitingForReset: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super({ key: 'GameScene' });
|
||||
}
|
||||
|
||||
create() {
|
||||
console.log('[GameScene] Creating scene...');
|
||||
|
||||
// Reset goal timer flags
|
||||
this.goalResetTimer = 0;
|
||||
this.isWaitingForReset = false;
|
||||
|
||||
this.drawRink();
|
||||
this.createGoals();
|
||||
this.createPuck();
|
||||
this.createPlayers();
|
||||
this.setupEventListeners();
|
||||
this.createPauseButton();
|
||||
console.log('[GameScene] Scene created. Players:', this.players.length);
|
||||
}
|
||||
|
||||
private createPlayers() {
|
||||
@ -210,7 +221,9 @@ export class GameScene extends Phaser.Scene {
|
||||
// Stop the puck (caught by net)
|
||||
this.puck.body.setVelocity(0, 0);
|
||||
|
||||
// Future: update score, trigger celebration, reset to faceoff, etc.
|
||||
// Start 3-second countdown to reset
|
||||
this.goalResetTimer = 3000;
|
||||
this.isWaitingForReset = true;
|
||||
});
|
||||
}
|
||||
|
||||
@ -327,6 +340,17 @@ export class GameScene extends Phaser.Scene {
|
||||
update(_time: number, delta: number) {
|
||||
if (this.isPaused) return;
|
||||
|
||||
// Handle goal reset timer
|
||||
if (this.isWaitingForReset) {
|
||||
this.goalResetTimer -= delta;
|
||||
if (this.goalResetTimer <= 0) {
|
||||
// Clean up before restart
|
||||
this.events.off('goal');
|
||||
this.scene.restart();
|
||||
}
|
||||
return; // Don't update anything while waiting for reset
|
||||
}
|
||||
|
||||
this.updatePuck();
|
||||
this.updatePlayers(delta);
|
||||
this.checkGoals();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user