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

@ -28,10 +28,10 @@ export const FPS = 60;
export const DEBUG = false; export const DEBUG = false;
// Player constants // Player constants
export const PLAYER_RADIUS_GOALIE = 12; // pixels export const PLAYER_RADIUS_GOALIE = 12; // pixels
export const PLAYER_RADIUS_SKATER = 10; // pixels export const PLAYER_RADIUS_SKATER = 10; // pixels
export const PLAYER_ROTATION_SPEED = 10; // radians per second export const PLAYER_ROTATION_SPEED = 10; // radians per second
export const SPEED_SCALE_FACTOR = 10; // speed attribute (0-100) / 10 = m/s export const SPEED_SCALE_FACTOR = 10; // speed attribute (0-100) / 10 = m/s
export const GOAL_DECELERATION_RATE = 0.9; // Speed multiplier reduction after goal export const GOAL_DECELERATION_RATE = 0.9; // Speed multiplier reduction after goal
// Movement constants // Movement constants
@ -40,7 +40,7 @@ export const PLAYER_ACCELERATION = 10; // m/s² - how quickly player reache
export const PLAYER_DECELERATION = 20; // m/s² - how quickly player stops export const PLAYER_DECELERATION = 20; // m/s² - how quickly player stops
// Puck constants // Puck constants
export const PUCK_RADIUS = 0.2; // meters (regulation hockey puck is ~7.6cm diameter, make it larger to be visible) export const PUCK_RADIUS = 0.2; // meters (regulation hockey puck is ~7.6cm diameter, make it larger to be visible)
export const PUCK_PICKUP_RADIUS = 1.5; // meters export const PUCK_PICKUP_RADIUS = 1.5; // meters
export const PUCK_CARRY_DISTANCE = 1.0; // meters in front of player export const PUCK_CARRY_DISTANCE = 1.0; // meters in front of player
export const MAX_PUCK_VELOCITY = 50; // m/s export const MAX_PUCK_VELOCITY = 50; // m/s
@ -55,11 +55,12 @@ export const FACEOFF_CIRCLE_RADIUS = 4.5; // meters
export const CENTER_DOT_RADIUS = 5; // pixels export const CENTER_DOT_RADIUS = 5; // pixels
// AI/Behavior constants // AI/Behavior constants
export const SHOOTING_RANGE = 10; // meters - max distance to attempt shot export const SHOOTING_RANGE = 10; // meters - max distance to attempt shot
export const SHOOTING_ANGLE_THRESHOLD = Math.PI / 4; // radians (45 degrees) export const SHOOTING_ANGLE_THRESHOLD = Math.PI / 4; // radians (45 degrees)
export const GOALIE_RANGE = 3; // meters - how far goalie moves from center export const GOALIE_RANGE = 3; // meters - how far goalie moves from center
// Tackle constants // Tackle constants
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
);
} }
} }
} }