diff --git a/src/config/constants.ts b/src/config/constants.ts index 08129c9..f12bd03 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -56,7 +56,10 @@ export const CENTER_DOT_RADIUS = 5; // pixels // AI/Behavior constants export const SHOOTING_RANGE = 10; // meters - max distance to attempt shot -export const SHOOTING_ANGLE_THRESHOLD = Math.PI / 3; // radians (60 degrees) +export const SHOOTING_ANGLE_THRESHOLD = Math.PI / 3; // radians (2=90 degrees, 3=60, 4=45) +export const CLOSE_RANGE_DISTANCE = 3; // meters - distance for close-range shots (backhands, etc.) +export const CLOSE_RANGE_ANGLE_THRESHOLD = (2 * Math.PI) / 3; // radians (120°) - wider angle for close shots +export const CLOSE_RANGE_SHOT_SPEED_MULTIPLIER = 0.6; // Close-range shots have less power export const GOALIE_RANGE = 3; // meters - how far goalie moves from center // Collision avoidance constants @@ -85,3 +88,7 @@ export const TACKLE_CLOSING_SPEED_WEAK = 1; // m/s - very weak check export const TACKLE_CLOSING_SPEED_SOLID = 3; // m/s - solid check export const TACKLE_VELOCITY_MODIFIER_MIN = 0.3; // Minimum modifier for very low closing speed export const TACKLE_VELOCITY_MODIFIER_MAX = 1.5; // Maximum modifier for high closing speed + +// Puck bounce constants +export const POST_BOUNCE_SPEED_REDUCTION = 0.7; // Puck loses 30% speed on post bounce +export const POST_BOUNCE_ANGLE_RANDOMNESS = 0.3; // Radians (~17 degrees) of random angle variation diff --git a/src/game/GameScene.ts b/src/game/GameScene.ts index f3db32d..fe47020 100644 --- a/src/game/GameScene.ts +++ b/src/game/GameScene.ts @@ -29,7 +29,9 @@ import { TACKLE_CLOSING_SPEED_WEAK, TACKLE_CLOSING_SPEED_SOLID, TACKLE_VELOCITY_MODIFIER_MIN, - TACKLE_VELOCITY_MODIFIER_MAX + TACKLE_VELOCITY_MODIFIER_MAX, + POST_BOUNCE_SPEED_REDUCTION, + POST_BOUNCE_ANGLE_RANDOMNESS } from '../config/constants'; import { Goal } from './Goal'; import { Puck } from '../entities/Puck'; @@ -64,7 +66,7 @@ export class GameScene extends Phaser.Scene { 'home', 'C', -1, - -1, + 0, { speed: 70, skill: 75, tackling: 70, balance: 75 } ); @@ -74,7 +76,7 @@ export class GameScene extends Phaser.Scene { 'away-LD', 'away', 'LD', - 15, + -15, 0, { speed: 80, skill: 70, tackling: 85, balance: 80 } ); @@ -106,15 +108,15 @@ export class GameScene extends Phaser.Scene { private createPuck() { // Initialize puck at center ice (0, 0 in game coordinates) - this.puck = new Puck(this, 0, 0); + this.puck = new Puck(this, 20, 5); - // Add collisions between puck and goal posts - this.physics.add.collider(this.puck, this.leftGoal.getLeftPost()); - this.physics.add.collider(this.puck, this.leftGoal.getRightPost()); - this.physics.add.collider(this.puck, this.leftGoal.getBackBar()); - this.physics.add.collider(this.puck, this.rightGoal.getLeftPost()); - this.physics.add.collider(this.puck, this.rightGoal.getRightPost()); - this.physics.add.collider(this.puck, this.rightGoal.getBackBar()); + // Add collisions between puck and goal posts with custom bounce handler + this.physics.add.collider(this.puck, this.leftGoal.getLeftPost(), this.handlePuckPostBounce, undefined, this); + this.physics.add.collider(this.puck, this.leftGoal.getRightPost(), this.handlePuckPostBounce, undefined, this); + this.physics.add.collider(this.puck, this.leftGoal.getBackBar(), this.handlePuckPostBounce, undefined, this); + this.physics.add.collider(this.puck, this.rightGoal.getLeftPost(), this.handlePuckPostBounce, undefined, this); + this.physics.add.collider(this.puck, this.rightGoal.getRightPost(), this.handlePuckPostBounce, undefined, this); + this.physics.add.collider(this.puck, this.rightGoal.getBackBar(), this.handlePuckPostBounce, undefined, this); } private createGoals() { @@ -260,6 +262,34 @@ export class GameScene extends Phaser.Scene { }); } + /** + * Handle puck bouncing off goal posts with randomized angle and speed reduction + */ + private handlePuckPostBounce() { + // Get current puck velocity + const vx = this.puck.body.velocity.x; + const vy = this.puck.body.velocity.y; + + // Calculate current angle and speed + const currentAngle = Math.atan2(vy, vx); + const currentSpeed = Math.sqrt(vx * vx + vy * vy); + + // Add random variation to bounce angle (-0.3 to +0.3 radians, ~±17 degrees) + const randomAngle = (Math.random() - 0.5) * 2 * POST_BOUNCE_ANGLE_RANDOMNESS; + const newAngle = currentAngle + randomAngle; + + // Reduce speed by 30% + const newSpeed = currentSpeed * POST_BOUNCE_SPEED_REDUCTION; + + // Apply new velocity + this.puck.body.setVelocity( + Math.cos(newAngle) * newSpeed, + Math.sin(newAngle) * newSpeed + ); + + console.log(`[Post bounce] Speed: ${(currentSpeed / SCALE).toFixed(1)} → ${(newSpeed / SCALE).toFixed(1)} m/s, Angle variation: ${(randomAngle * 180 / Math.PI).toFixed(1)}°`); + } + private executeShot(player: Player, targetX: number, targetY: number) { console.log(`${player.id} shoots toward (${targetX}, ${targetY})`);