Refactor THREAT_DETECTION_RADIUS to NEAR_PLAYER_DETECTION_RADIUS for general use

- Renamed constant to reflect general-purpose nature (can be used by any behavior, not just puck carriers)
- Moved detection circle rendering from PuckCarrierBehavior to Player class
- Detection circle now renders for all players in DEBUG mode, not just puck carriers
- Updated all references and comments to use new naming

🤖 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-03 13:25:33 +02:00
parent 1aa18376d5
commit c749308b49
3 changed files with 19 additions and 16 deletions

View File

@ -72,7 +72,7 @@ export const CLOSE_RANGE_SHOT_SPEED_MULTIPLIER = 0.6; // Close-range shots have
export const GOALIE_RANGE = 3; // meters - how far goalie moves from center export const GOALIE_RANGE = 3; // meters - how far goalie moves from center
// Collision avoidance constants // Collision avoidance constants
export const THREAT_DETECTION_RADIUS = 4; // meters - radius to detect approaching opponents export const NEAR_PLAYER_DETECTION_RADIUS = 4; // meters - radius to detect nearby players (threats, teammates, etc.)
export const EVASION_ANGLE = Math.PI / 3; // radians (60 degrees) - angle to turn when evading export const EVASION_ANGLE = Math.PI / 3; // radians (60 degrees) - angle to turn when evading
// Tackle constants // Tackle constants

View File

@ -11,7 +11,8 @@ import {
TACKLE_COOLDOWN, TACKLE_COOLDOWN,
TACKLE_FALL_DURATION, TACKLE_FALL_DURATION,
PLAYER_ACCELERATION, PLAYER_ACCELERATION,
PLAYER_DECELERATION PLAYER_DECELERATION,
NEAR_PLAYER_DETECTION_RADIUS
} from '../config/constants'; } from '../config/constants';
import { CoordinateUtils } from '../utils/coordinates'; import { CoordinateUtils } from '../utils/coordinates';
import { MathUtils } from '../utils/math'; import { MathUtils } from '../utils/math';
@ -56,6 +57,7 @@ export class Player extends Phaser.GameObjects.Container {
// Debug visualizations // Debug visualizations
private debugTargetGraphics?: Phaser.GameObjects.Graphics; private debugTargetGraphics?: Phaser.GameObjects.Graphics;
private debugLineGraphics?: Phaser.GameObjects.Graphics; private debugLineGraphics?: Phaser.GameObjects.Graphics;
private debugDetectionCircle?: Phaser.GameObjects.Graphics;
// Direction indicator // Direction indicator
private directionIndicator!: Phaser.GameObjects.Graphics; private directionIndicator!: Phaser.GameObjects.Graphics;
@ -100,6 +102,7 @@ export class Player extends Phaser.GameObjects.Container {
if (DEBUG) { if (DEBUG) {
this.debugTargetGraphics = scene.add.graphics(); this.debugTargetGraphics = scene.add.graphics();
this.debugLineGraphics = scene.add.graphics(); this.debugLineGraphics = scene.add.graphics();
this.debugDetectionCircle = scene.add.graphics();
} }
} }
@ -323,10 +326,10 @@ export class Player extends Phaser.GameObjects.Container {
} }
/** /**
* Update debug visualizations (target position and path line) * Update debug visualizations (target position, path line, and detection circle)
*/ */
private updateDebugVisuals() { private updateDebugVisuals() {
if (!DEBUG || !this.debugTargetGraphics || !this.debugLineGraphics) return; if (!DEBUG || !this.debugTargetGraphics || !this.debugLineGraphics || !this.debugDetectionCircle) return;
// Convert target position to screen coordinates // Convert target position to screen coordinates
const targetScreen = CoordinateUtils.gameToScreen(this.scene, this.targetX, this.targetY); const targetScreen = CoordinateUtils.gameToScreen(this.scene, this.targetX, this.targetY);
@ -335,6 +338,7 @@ export class Player extends Phaser.GameObjects.Container {
// Clear previous debug graphics // Clear previous debug graphics
this.debugTargetGraphics.clear(); this.debugTargetGraphics.clear();
this.debugLineGraphics.clear(); this.debugLineGraphics.clear();
this.debugDetectionCircle.clear();
// Draw line from player to target // Draw line from player to target
const lineColor = this.team === 'home' ? 0x0000ff : 0xff0000; const lineColor = this.team === 'home' ? 0x0000ff : 0xff0000;
@ -356,5 +360,9 @@ export class Player extends Phaser.GameObjects.Container {
targetScreen.x - markerSize, targetScreen.x - markerSize,
targetScreen.y + markerSize targetScreen.y + markerSize
); );
// Draw near player detection circle (always visible in DEBUG mode)
this.debugDetectionCircle.lineStyle(2, 0xff00ff, 0.3); // Magenta circle with lower opacity
this.debugDetectionCircle.strokeCircle(playerScreen.x, playerScreen.y, NEAR_PLAYER_DETECTION_RADIUS * SCALE);
} }
} }

View File

@ -7,10 +7,9 @@ import {
SHOOTING_ANGLE_THRESHOLD, SHOOTING_ANGLE_THRESHOLD,
CLOSE_RANGE_DISTANCE, CLOSE_RANGE_DISTANCE,
CLOSE_RANGE_ANGLE_THRESHOLD, CLOSE_RANGE_ANGLE_THRESHOLD,
THREAT_DETECTION_RADIUS, NEAR_PLAYER_DETECTION_RADIUS,
EVASION_ANGLE, EVASION_ANGLE,
DEBUG, DEBUG
SCALE
} from '../../../config/constants'; } from '../../../config/constants';
import { MathUtils } from '../../../utils/math'; import { MathUtils } from '../../../utils/math';
import { CoordinateUtils } from '../../../utils/coordinates'; import { CoordinateUtils } from '../../../utils/coordinates';
@ -97,7 +96,7 @@ export class PuckCarrierBehavior extends BehaviorNode {
* Returns evasion target if threat detected, null otherwise * Returns evasion target if threat detected, null otherwise
* *
* The player will maintain evasion as long as an opponent is: * The player will maintain evasion as long as an opponent is:
* 1. Within the threat detection radius (close proximity) * 1. Within the near player detection radius (close proximity)
* *
* Once an evasion direction is chosen, it persists until the opponent * Once an evasion direction is chosen, it persists until the opponent
* leaves the threat zone to prevent direction flipping. * leaves the threat zone to prevent direction flipping.
@ -127,13 +126,9 @@ export class PuckCarrierBehavior extends BehaviorNode {
const goalY = 0; const goalY = 0;
const toGoalAngle = Math.atan2(goalY - player.gameY, opponentGoalX - player.gameX); const toGoalAngle = Math.atan2(goalY - player.gameY, opponentGoalX - player.gameX);
// Draw debug threat zone circle // Draw debug line to goal (circle is now rendered by Player class)
if (DEBUG && debugGraphics) { if (DEBUG && debugGraphics) {
const playerScreen = CoordinateUtils.gameToScreen(player.scene, player.gameX, player.gameY); const playerScreen = CoordinateUtils.gameToScreen(player.scene, player.gameX, player.gameY);
debugGraphics.lineStyle(2, 0xff00ff, 0.5); // Magenta circle
debugGraphics.strokeCircle(playerScreen.x, playerScreen.y, THREAT_DETECTION_RADIUS * SCALE);
// Draw line to goal
const goalScreen = CoordinateUtils.gameToScreen(player.scene, opponentGoalX, goalY); const goalScreen = CoordinateUtils.gameToScreen(player.scene, opponentGoalX, goalY);
debugGraphics.lineStyle(1, 0x00ff00, 0.3); // Green line to goal debugGraphics.lineStyle(1, 0x00ff00, 0.3); // Green line to goal
debugGraphics.lineBetween(playerScreen.x, playerScreen.y, goalScreen.x, goalScreen.y); debugGraphics.lineBetween(playerScreen.x, playerScreen.y, goalScreen.x, goalScreen.y);
@ -149,7 +144,7 @@ export class PuckCarrierBehavior extends BehaviorNode {
const distanceToOpponent = MathUtils.distance(player.gameX, player.gameY, opponent.gameX, opponent.gameY); const distanceToOpponent = MathUtils.distance(player.gameX, player.gameY, opponent.gameX, opponent.gameY);
// If opponent still in threat zone, maintain the evasion // If opponent still in threat zone, maintain the evasion
if (distanceToOpponent <= THREAT_DETECTION_RADIUS) { if (distanceToOpponent <= NEAR_PLAYER_DETECTION_RADIUS) {
const evasionAngle = evasion.side === 'left' ? toGoalAngle + EVASION_ANGLE : toGoalAngle - EVASION_ANGLE; const evasionAngle = evasion.side === 'left' ? toGoalAngle + EVASION_ANGLE : toGoalAngle - EVASION_ANGLE;
const evasionDistance = 20; const evasionDistance = 20;
const evasionTargetX = player.gameX + Math.cos(evasionAngle) * evasionDistance; const evasionTargetX = player.gameX + Math.cos(evasionAngle) * evasionDistance;
@ -200,14 +195,14 @@ export class PuckCarrierBehavior extends BehaviorNode {
const distanceToOpponent = MathUtils.distance(player.gameX, player.gameY, opponent.gameX, opponent.gameY); const distanceToOpponent = MathUtils.distance(player.gameX, player.gameY, opponent.gameX, opponent.gameY);
// Debug: Draw all opponents in threat zone // Debug: Draw all opponents in threat zone
if (DEBUG && debugGraphics && distanceToOpponent <= THREAT_DETECTION_RADIUS) { if (DEBUG && debugGraphics && distanceToOpponent <= NEAR_PLAYER_DETECTION_RADIUS) {
const opponentScreen = CoordinateUtils.gameToScreen(player.scene, opponent.gameX, opponent.gameY); const opponentScreen = CoordinateUtils.gameToScreen(player.scene, opponent.gameX, opponent.gameY);
debugGraphics.lineStyle(2, 0xffa500, 0.6); // Orange circle debugGraphics.lineStyle(2, 0xffa500, 0.6); // Orange circle
debugGraphics.strokeCircle(opponentScreen.x, opponentScreen.y, 12); debugGraphics.strokeCircle(opponentScreen.x, opponentScreen.y, 12);
} }
// Check if opponent is within threat zone // Check if opponent is within threat zone
if (distanceToOpponent <= THREAT_DETECTION_RADIUS) { if (distanceToOpponent <= NEAR_PLAYER_DETECTION_RADIUS) {
// Calculate angle from player to opponent // Calculate angle from player to opponent
const angleToOpponent = Math.atan2( const angleToOpponent = Math.atan2(
opponent.gameY - player.gameY, opponent.gameY - player.gameY,