From 326b3036b60d8d4ace87dde13d9ed153d8941978 Mon Sep 17 00:00:00 2001 From: Pierre Wessman <4029607+pierrewessman@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:48:30 +0200 Subject: [PATCH] puck handling --- src/entities/puck.js | 51 +++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/entities/puck.js b/src/entities/puck.js index 81ea8b3..5fdb406 100644 --- a/src/entities/puck.js +++ b/src/entities/puck.js @@ -31,25 +31,42 @@ class Puck { const puckCarrier = players.find(player => player.state.hasPuck); if (!puckCarrier) return; - const distance = this.position.distance(puckCarrier.position); - const maxPossessionDistance = 25; // Maximum distance to maintain puck possession + // Check if any opponent is trying to steal the puck + const opponents = players.filter(p => p.team !== puckCarrier.team && p.role !== 'G'); + const nearbyOpponent = opponents.find(opponent => { + const distanceToCarrier = opponent.position.distance(puckCarrier.position); + const distanceToPuck = opponent.position.distance(this.position); + return distanceToCarrier < 25 && distanceToPuck < 20; + }); - if (distance > maxPossessionDistance) { - puckCarrier.state.hasPuck = false; - // Puck becomes loose and slightly moves in a random direction - if (this.velocity.magnitude() < 10) { - const randomDirection = new Vector2( - (Math.random() - 0.5) * 2, - (Math.random() - 0.5) * 2 - ).normalize(); - this.velocity = randomDirection.multiply(20); + if (nearbyOpponent) { + // Opponent is close enough to potentially steal the puck + const stealChance = 0.005; // 0.5% chance per frame (roughly 30% per second at 60fps) + if (Math.random() < stealChance) { + puckCarrier.state.hasPuck = false; + nearbyOpponent.state.hasPuck = true; + this.lastPlayerTouch = nearbyOpponent; + this.lastTeamTouch = nearbyOpponent.team; + return; } - } else if (distance < 15) { - // Keep puck close to player when they have possession - const directionToPlayer = puckCarrier.position.subtract(this.position).normalize(); - this.position = puckCarrier.position.subtract(directionToPlayer.multiply(12)); - this.velocity = puckCarrier.velocity.multiply(0.8); } + + // Sticky puck logic - keep puck attached to carrier + const stickDistance = 15; // Distance puck stays from player + const directionToPlayer = puckCarrier.position.subtract(this.position).normalize(); + + // Position puck slightly in front of player based on their movement direction + let puckOffset; + if (puckCarrier.velocity.magnitude() > 10) { + // When moving, position puck in front of player + puckOffset = puckCarrier.velocity.normalize().multiply(stickDistance); + } else { + // When stationary, keep puck close + puckOffset = directionToPlayer.multiply(-stickDistance); + } + + this.position = puckCarrier.position.add(puckOffset); + this.velocity = puckCarrier.velocity.multiply(1.0); // Match player velocity } updateTrail() { @@ -161,7 +178,7 @@ class Puck { this.velocity = this.velocity.subtract(direction.multiply(impulse * player.mass * this.restitution)); - if (this.velocity.magnitude() < 100 && player.role !== 'G') { + if (player.role !== 'G') { this.pickupPuck(player, gameState, players); } else if (player.role === 'G' && this.velocity.magnitude() > 50) { this.handleGoalieSave(player, gameState);