Add player fall mechanic after successful tackles

When a player is successfully tackled, they now experience a realistic fall animation:
- Immediately decelerate to 0 velocity
- Stay down for 500ms (configurable via TACKLE_FALL_DURATION)
- Resume normal movement after recovery period

Changes:
- Added TACKLE_FALL_DURATION constant (500ms)
- Added fall state tracking to Player class (isFallen, fallRecoveryTime)
- Implemented fall() method to trigger the fall state
- Updated update() to handle fallen state and prevent movement during recovery
- Modified executeTackle() to call fall() instead of just reducing velocity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Pierre Wessman 2025-10-02 11:14:53 +02:00
parent c81e500e18
commit 999003b012
3 changed files with 42 additions and 13 deletions

View File

@ -63,3 +63,4 @@ export const GOALIE_RANGE = 3; // meters - how far goalie mo
export const TACKLE_SUCCESS_MODIFIER = 1; // Multiplier for tackle success calculation (balancing) export const TACKLE_SUCCESS_MODIFIER = 1; // Multiplier for tackle success calculation (balancing)
export const TACKLE_PUCK_LOOSE_CHANCE = 0.6; // Chance puck becomes loose after tackle export const TACKLE_PUCK_LOOSE_CHANCE = 0.6; // Chance puck becomes loose after tackle
export const TACKLE_COOLDOWN = 1000; // ms - time between tackles for same player export const TACKLE_COOLDOWN = 1000; // ms - time between tackles for same player
export const TACKLE_FALL_DURATION = 500; // ms - time player stays down after being tackled

View File

@ -9,6 +9,7 @@ import {
GOAL_DECELERATION_RATE, GOAL_DECELERATION_RATE,
DEBUG, DEBUG,
TACKLE_COOLDOWN, TACKLE_COOLDOWN,
TACKLE_FALL_DURATION,
PLAYER_ACCELERATION, PLAYER_ACCELERATION,
PLAYER_DECELERATION PLAYER_DECELERATION
} from '../config/constants'; } from '../config/constants';
@ -48,6 +49,10 @@ export class Player extends Phaser.GameObjects.Container {
// Tackle cooldown tracking // Tackle cooldown tracking
private lastTackleTime: number = 0; private lastTackleTime: number = 0;
// Fall state tracking (when tackled)
private isFallen: boolean = false;
private fallRecoveryTime: number = 0;
// Debug visualizations // Debug visualizations
private debugTargetGraphics?: Phaser.GameObjects.Graphics; private debugTargetGraphics?: Phaser.GameObjects.Graphics;
private debugLineGraphics?: Phaser.GameObjects.Graphics; private debugLineGraphics?: Phaser.GameObjects.Graphics;
@ -200,6 +205,21 @@ export class Player extends Phaser.GameObjects.Container {
public update(delta: number) { public update(delta: number) {
const deltaSeconds = delta / 1000; const deltaSeconds = delta / 1000;
// Check if player is fallen and should stay still
if (this.isFallen) {
const currentTime = Date.now();
if (currentTime < this.fallRecoveryTime) {
// Player is still down - force zero velocity
this.currentSpeed = 0;
this.body.setVelocity(0, 0);
return;
} else {
// Recovery time elapsed - player can move again
this.isFallen = false;
}
}
// Calculate distance to target // Calculate distance to target
const distance = MathUtils.distance(this.gameX, this.gameY, this.targetX, this.targetY); const distance = MathUtils.distance(this.gameX, this.gameY, this.targetX, this.targetY);
@ -293,6 +313,17 @@ export class Player extends Phaser.GameObjects.Container {
this.lastTackleTime = Date.now(); this.lastTackleTime = Date.now();
} }
/**
* Make player fall (when successfully tackled)
* Player decelerates to 0 and stays down for TACKLE_FALL_DURATION ms
*/
public fall() {
this.isFallen = true;
this.fallRecoveryTime = Date.now() + TACKLE_FALL_DURATION;
this.currentSpeed = 0;
this.body.setVelocity(0, 0);
}
/** /**
* Update debug visualizations (target position and path line) * Update debug visualizations (target position and path line)
*/ */

View File

@ -339,11 +339,8 @@ export class GameScene extends Phaser.Scene {
} }
} }
// Apply physical impact to tackled player (significantly slow them down) // Make tackled player fall
tackled.body.setVelocity( tackled.fall();
tackled.body.velocity.x * 0.1,
tackled.body.velocity.y * 0.1
);
} }
} }
} }