From 15c24608d4ebf24abee0e85d54999cffde482f4e Mon Sep 17 00:00:00 2001 From: Pierre Wessman <4029607+pierrewessman@users.noreply.github.com> Date: Fri, 19 Sep 2025 13:14:43 +0200 Subject: [PATCH] Fix goal detection to match light red goal areas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update isInGoal() to check actual goal area boundaries (goalXOffset ± goalDepth) - Update handleGoal() to use consistent goal area coordinates - Add continuous goal checking in puck update loop - Add goal post collision detection to prevent entry from sides/behind - Goals now only register when puck enters light red areas from the front 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/entities/puck.js | 77 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/src/entities/puck.js b/src/entities/puck.js index e2b5357..8cadc2a 100644 --- a/src/entities/puck.js +++ b/src/entities/puck.js @@ -20,6 +20,11 @@ class Puck { this.checkPlayerCollisions(players, gameState); this.checkPuckPossession(players); this.updateTrail(); + + // Check for goals continuously, not just on board collisions + if (this.isInGoal(gameState)) { + this.handleGoal(gameState); + } } updatePosition(deltaTime) { @@ -152,7 +157,7 @@ class Puck { collision = true; } - // Check left goal side walls + // Check left goal side walls and front posts if (this.position.x >= leftGoalLeft && this.position.x <= leftGoalRight) { // Top side wall if (this.position.y - this.radius <= leftGoalTop && this.position.y >= leftGoalTop - 20) { @@ -168,6 +173,22 @@ class Puck { } } + // Check left goal front posts (prevent entering from sides) + if (this.position.x + this.radius >= leftGoalRight && this.position.x <= leftGoalRight + 10) { + // Top post + if (this.position.y >= leftGoalTop - 10 && this.position.y <= leftGoalTop + 10) { + this.velocity.x = -Math.abs(this.velocity.x); + this.position.x = leftGoalRight - this.radius; + collision = true; + } + // Bottom post + if (this.position.y >= leftGoalBottom - 10 && this.position.y <= leftGoalBottom + 10) { + this.velocity.x = -Math.abs(this.velocity.x); + this.position.x = leftGoalRight - this.radius; + collision = true; + } + } + // Check right goal side walls if (this.position.x >= rightGoalLeft && this.position.x <= rightGoalRight) { // Top side wall @@ -184,15 +205,45 @@ class Puck { } } + // Check right goal front posts (prevent entering from sides) + if (this.position.x - this.radius <= rightGoalLeft && this.position.x >= rightGoalLeft - 10) { + // Top post + if (this.position.y >= rightGoalTop - 10 && this.position.y <= rightGoalTop + 10) { + this.velocity.x = Math.abs(this.velocity.x); + this.position.x = rightGoalLeft + this.radius; + collision = true; + } + // Bottom post + if (this.position.y >= rightGoalBottom - 10 && this.position.y <= rightGoalBottom + 10) { + this.velocity.x = Math.abs(this.velocity.x); + this.position.x = rightGoalLeft + this.radius; + collision = true; + } + } + return collision; } isInGoal(gameState) { - const goalY = gameState.rink.centerY; - const goalHeight = gameState.rink.goalHeight; + const rink = gameState.rink; + const goalY = rink.centerY; + const goalHeight = rink.goalHeight; + const goalDepth = 25; + const goalXOffset = gameState.renderer?.goalXOffset || 80; + // Check if puck is in the vertical range of the goals if (this.position.y >= goalY - goalHeight && this.position.y <= goalY + goalHeight) { - if (this.position.x <= 20 || this.position.x >= gameState.rink.width - 20) { + // Left goal (light red area) + const leftGoalRight = goalXOffset; + const leftGoalLeft = goalXOffset - goalDepth; + + // Right goal (light red area) + const rightGoalLeft = rink.width - goalXOffset; + const rightGoalRight = rink.width - goalXOffset + goalDepth; + + // Check if puck is inside either light red goal area + if ((this.position.x >= leftGoalLeft && this.position.x <= leftGoalRight) || + (this.position.x >= rightGoalLeft && this.position.x <= rightGoalRight)) { return true; } } @@ -203,13 +254,27 @@ class Puck { // Determine which goal was scored in and validate the direction let scoringTeam = null; - if (this.position.x <= 20) { + const rink = gameState.rink; + const goalY = rink.centerY; + const goalHeight = rink.goalHeight; + const goalDepth = 25; + const goalXOffset = gameState.renderer?.goalXOffset || 80; + + // Left goal (light red area) + const leftGoalRight = goalXOffset; + const leftGoalLeft = goalXOffset - goalDepth; + + // Right goal (light red area) + const rightGoalLeft = rink.width - goalXOffset; + const rightGoalRight = rink.width - goalXOffset + goalDepth; + + if (this.position.x >= leftGoalLeft && this.position.x <= leftGoalRight) { // Puck is in the LEFT goal (home team's goal) // Only count as goal if puck came from the right side (positive x velocity) if (this.velocity.x > 0 || (this.lastTeamTouch === 'away')) { scoringTeam = 'away'; // Away team scored on home team's goal } - } else if (this.position.x >= gameState.rink.width - 20) { + } else if (this.position.x >= rightGoalLeft && this.position.x <= rightGoalRight) { // Puck is in the RIGHT goal (away team's goal) // Only count as goal if puck came from the left side (negative x velocity) if (this.velocity.x < 0 || (this.lastTeamTouch === 'home')) {