Drawaria Physics Engine Basketball🏀

Advanced physics-based basketball engine with professional NBA court and possession system!

// ==UserScript==
// @name         Drawaria Physics Engine Basketball🏀
// @namespace    http://tampermonkey.net/
// @version      6.1.0
// @description  Advanced physics-based basketball engine with professional NBA court and possession system!
// @author       YouTubeDrawaria
// @match        https://drawaria.online/*
// @grant        none
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// ==/UserScript==

(function() {
    'use strict';

    /* ---------- SHARED SYSTEM COMPONENTS ---------- */
    let drawariaSocket = null;
    let drawariaCanvas = null;
    let drawariaCtx = null;

    // Optimized command queue
    const commandQueue = [];
    let batchProcessor = null;
    const BATCH_SIZE = 12;
    const BATCH_INTERVAL = 45;

    const positionCache = new Map();
    const MOVEMENT_THRESHOLD = 3;

    // Basketball-specific constants
    const PHYSICS_CONSTANTS = {
        GRAVITY: 400,
        BALL_MASS: 0.2,
        BALL_RADIUS: 25,
        TIMESTEP: 1/60,
        MAX_VELOCITY: 600,
        AIR_RESISTANCE: 0.005,
        RESTITUTION_BALL: 0.85,
        RESTITUTION_WALL: 0.7,
        FRICTION_COURT: 0.75,
        PLAYER_INTERACTION_FORCE: 250,
        PLAYER_PUSH_MULTIPLIER: 1.8,
        PLAYER_RESTITUTION: 0.9,
        PLAYER_DETECTION_INTERVAL: 1000 / 60,
        PLAYER_DETECTION_RADIUS_MULTIPLIER: 2.0,
        DRIBBLE_FORCE: 150,
        POSSESSION_DISTANCE: 80,
        BALL_COLOR: '#FF8C00',
        STEAL_COOLDOWN: 1000,
    };

    // Professional NBA Court Constants (from first script)
    const NBA_COURT_CONSTANTS = {
        COURT_COLOR: '#D2691E',      // Madera de cancha
        LINE_COLOR: '#FF4555',       // Líneas blancas oficiales
        RIM_COLOR: '#787878',        // Aros grises metálicos
        BACKBOARD_COLOR: '#787878',  // Tableros blancos
        KEY_COLOR: '#FF4500',        // Área restringida naranja
        TEXT_COLOR: '#000000',       // Texto negro
        POLE_COLOR: '#696969',       // Postes grises
        NET_COLOR: '#787878',        // Red blanca
        RIM_THICKNESS: 8,
        LINE_THICKNESS_MULTIPLIER: 0.008
    };

    const MATCH_CONSTANTS = {
        MAX_BASKETS: 5,
        PLAY_AREA_REDUCTION: {
            SIDES: 0.1,
            TOP: 0.4
        }
    };

    // WebSocket interception
    const originalWebSocketSend = WebSocket.prototype.send;
    WebSocket.prototype.send = function (...args) {
        if (!drawariaSocket && this.url && this.url.includes('drawaria')) {
            drawariaSocket = this;
            console.log('🔗 Drawaria WebSocket captured for basketball engine.');
            startBatchProcessor();
        }
        return originalWebSocketSend.apply(this, args);
    };

    function startBatchProcessor() {
        if (batchProcessor) return;
        batchProcessor = setInterval(() => {
            if (!drawariaSocket || drawariaSocket.readyState !== WebSocket.OPEN || commandQueue.length === 0) {
                return;
            }
            const batch = commandQueue.splice(0, BATCH_SIZE);
            batch.forEach(cmd => {
                try { drawariaSocket.send(cmd); } catch (e) { console.warn('Failed to send command:', e); }
            });
        }, BATCH_INTERVAL);
    }

    function enqueueDrawCommand(x1, y1, x2, y2, color, thickness) {
        if (!drawariaCanvas || !drawariaSocket) return;

        const normX1 = (x1 / drawariaCanvas.width).toFixed(4);
        const normY1 = (y1 / drawariaCanvas.height).toFixed(4);
        const normX2 = (x2 / drawariaCanvas.width).toFixed(4);
        const normY2 = (y2 / drawariaCanvas.height).toFixed(4);

        const cmd = `42["drawcmd",0,[${normX1},${normY1},${normX2},${normY2},false,${-Math.abs(thickness)},"${color}",0,0,{}]]`;
        commandQueue.push(cmd);

        if (drawariaCtx) {
            drawariaCtx.strokeStyle = color;
            drawariaCtx.lineWidth = thickness;
            drawariaCtx.lineCap = 'round';
            drawariaCtx.lineJoin = 'round';
            drawariaCtx.beginPath();
            drawariaCtx.moveTo(x1, y1);
            drawariaCtx.lineTo(x2, y2);
            drawariaCtx.stroke();
        }
    }

    // Helper functions
    function clamp(value, min, max) { return Math.min(Math.max(value, min), max); }
    function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }

    /* ---------- ADVANCED BASKETBALL PHYSICS ENGINE ---------- */
    class AdvancedDrawariaBasketball {
        constructor() {
            this.initialized = false;
            this.isActive = false;
            this.physicsObjects = new Map();
            this.objectIdCounter = 0;
            this.lastRenderTime = 0;
            this.renderInterval = 1000 / 30;

            // Sistema de posesión de baloncesto
            this.possessionSystem = {
                ballOwner: null,
                lastStealTime: 0,
                dribbleInterval: null,
                possessionDistance: PHYSICS_CONSTANTS.POSSESSION_DISTANCE
            };

            // Match mode system
            this.matchMode = {
                active: false,
                scores: { p1: 0, p2: 0 },
                playArea: null,
                lastScorePositions: { p1: null, p2: null },
                goalCooldown: false
            };

            this.gameStats = {
                totalCollisions: 0,
                maxVelocityReached: 0,
                objectsCreated: 0,
                totalBaskets: 0
            };

            this.controls = {
                showTrails: false,
                showDebug: false,
                rainbowModeActive: false,
                defaultObjectColor: PHYSICS_CONSTANTS.BALL_COLOR,
                alternatePhysics: 'normal'
            };

            this.rainbowHue = 0;
            this.rainbowInterval = null;

            this.playerTracker = {
                players: new Map(),
                detectionRadius: PHYSICS_CONSTANTS.BALL_RADIUS * PHYSICS_CONSTANTS.PLAYER_DETECTION_RADIUS_MULTIPLIER,
                lastUpdateTime: 0
            };

            this.fieldDrawing = { isDrawing: false, isStopped: false };

            this.init();
        }

        init() {
            if (this.initialized) return;

            const checkGameReady = () => {
                const gameCanvas = document.getElementById('canvas');
                if (gameCanvas) {
                    this.canvasElement = gameCanvas;
                    drawariaCanvas = gameCanvas;
                    this.canvasContext = gameCanvas.getContext('2d');
                    drawariaCtx = gameCanvas.getContext('2d');

                    this.initialized = true;
                    this.createAdvancedPanel();
                    console.log('✅ Advanced Basketball Physics Engine v6.1 initialized with Professional NBA Court');
                } else {
                    setTimeout(checkGameReady, 100);
                }
            };
            checkGameReady();
        }

        createAdvancedPanel() {
            const existingPanel = document.getElementById('advanced-physics-panel');
            if (existingPanel) existingPanel.remove();

            const panel = document.createElement('div');
            panel.id = 'advanced-physics-panel';
            panel.style.cssText = `
                position: fixed !important;
                top: 20px !important;
                right: 20px !important;
                width: 380px !important;
                z-index: 2147483647 !important;
                background: linear-gradient(135deg, #0f0f23, #1a1a3a) !important;
                border: 2px solid #FF8C00 !important;
                border-radius: 15px !important;
                color: white !important;
                font-family: 'Segoe UI', Arial, sans-serif !important;
                overflow: hidden !important;
                box-shadow: 0 0 30px rgba(255,140,0,0.4) !important;
            `;

            // Header draggable
            const header = document.createElement('div');
            header.id = 'panel-header';
            header.style.cssText = `
                background: linear-gradient(45deg, #FF8C00, #FF6347) !important;
                padding: 12px 20px !important;
                font-weight: bold !important;
                text-align: center !important;
                font-size: 14px !important;
                cursor: move !important;
                user-select: none !important;
                display: flex !important;
                justify-content: space-between !important;
                align-items: center !important;
            `;

            const title = document.createElement('div');
            title.innerHTML = '🏀 NBA BASKETBALL ENGINE v6.1';
            title.style.flex = '1';

            const buttonContainer = document.createElement('div');
            buttonContainer.style.cssText = `display: flex !important; gap: 8px !important;`;

            // Botón minimizar
            const minimizeBtn = document.createElement('button');
            minimizeBtn.id = 'minimize-btn';
            minimizeBtn.innerHTML = '−';
            minimizeBtn.style.cssText = `
                width: 25px !important; height: 25px !important;
                background: rgba(255,255,255,0.2) !important;
                border: none !important; border-radius: 4px !important;
                color: white !important; cursor: pointer !important;
                font-size: 16px !important; line-height: 1 !important; padding: 0 !important;
            `;

            // Botón cerrar
            const closeBtn = document.createElement('button');
            closeBtn.id = 'close-btn';
            closeBtn.innerHTML = '×';
            closeBtn.style.cssText = `
                width: 25px !important; height: 25px !important;
                background: rgba(255,0,0,0.6) !important;
                border: none !important; border-radius: 4px !important;
                color: white !important; cursor: pointer !important;
                font-size: 18px !important; line-height: 1 !important; padding: 0 !important;
            `;

            buttonContainer.appendChild(minimizeBtn);
            buttonContainer.appendChild(closeBtn);
            header.appendChild(title);
            header.appendChild(buttonContainer);

            // Contenido del panel
            const content = document.createElement('div');
            content.id = 'panel-content';
            content.style.cssText = `padding: 20px !important;`;
            content.innerHTML = `
                <!-- CREATE PROFESSIONAL NBA COURT BUTTON -->
                <div style="margin-bottom: 15px; text-align: center;">
                    <button id="create-court-btn" style="
                        width: 100%;
                        padding: 12px;
                        background: linear-gradient(135deg, ${NBA_COURT_CONSTANTS.COURT_COLOR}, #CD853F);
                        color: white;
                        border: none;
                        border-radius: 8px;
                        cursor: pointer;
                        font-size: 14px;
                        font-weight: bold;
                        margin-bottom: 10px;
                    ">🏀 Create Professional NBA Court</button>
                </div>

                <!-- LAUNCH PHYSICS BUTTON -->
                <div style="margin-bottom: 15px; text-align: center;">
                    <button id="toggle-physics" style="
                        width: 100%;
                        padding: 12px;
                        background: linear-gradient(135deg, #FF8C00, #FF6347);
                        color: white;
                        border: none;
                        border-radius: 8px;
                        cursor: pointer;
                        font-size: 14px;
                        font-weight: bold;
                    ">🚀 Launch Basketball Engine</button>
                </div>

                <!-- OBJECT CREATION BUTTONS -->
                <div style="display: flex; gap: 10px; margin-bottom: 15px;">
                    <button id="add-basketball-btn" style="
                        flex: 1;
                        padding: 8px;
                        background: linear-gradient(135deg, #FF8C00, #FF6347);
                        color: white;
                        border: none;
                        border-radius: 6px;
                        cursor: pointer;
                        font-size: 12px;
                        font-weight: bold;
                    ">🏀 Basketball</button>
                </div>

                <!-- ACTION BUTTONS -->
                <div style="display: flex; gap: 8px; margin-bottom: 15px;">
                    <button id="reset-all-btn" style="
                        flex: 1;
                        padding: 8px;
                        background: linear-gradient(135deg, #74b9ff, #0984e3);
                        color: white;
                        border: none;
                        border-radius: 6px;
                        cursor: pointer;
                        font-weight: bold;
                        font-size: 11px;
                    ">🔄 Reset</button>
                </div>

                <!-- ADVANCED MODES -->
                <div style="margin-bottom: 15px;">
                    <h4 style="margin: 0 0 10px 0; font-size: 13px; color: #FF8C00; text-align: center;">🌟 Basketball Modes</h4>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
                        <button id="match-mode-toggle" class="mode-toggle" style="
                            padding: 8px;
                            background: linear-gradient(135deg, #444, #666);
                            color: white;
                            border: none;
                            border-radius: 6px;
                            cursor: pointer;
                            font-size: 10px;
                            font-weight: bold;
                        ">🏆 Match Mode</button>
                        <button id="clean-canvas-btn" style="
                            padding: 8px;
                            background: linear-gradient(135deg, #e17055, #d63031);
                            color: white;
                            border: none;
                            border-radius: 6px;
                            cursor: pointer;
                            font-size: 10px;
                            font-weight: bold;
                        ">🧹 Clean Canvas</button>
                    </div>
                </div>

                <!-- PHYSICS SELECTION -->
                <div style="margin-bottom: 15px;">
                    <label style="display: block; margin-bottom: 5px; font-size: 12px; color: #FF8C00;">
                        🔬 Physics Mode:
                    </label>
                    <select id="physics-mode" style="
                        width: 100%;
                        padding: 8px;
                        border: 1px solid #FF8C00;
                        border-radius: 6px;
                        background: #1a1a3a;
                        color: white;
                        font-size: 12px;
                    ">
                        <option value="normal">🏀 Normal</option>
                        <option value="moon">🌙 Moon Gravity</option>
                        <option value="underwater">🌊 Underwater</option>
                        <option value="magnetic">🧲 Magnetic Court</option>
                    </select>
                </div>

                <!-- CLEAR ALL -->
                <div style="margin-bottom: 15px;">
                    <button id="clear-all-btn" style="
                        width: 100%;
                        padding: 10px;
                        background: linear-gradient(135deg, #990000, #cc0000);
                        color: white;
                        border: none;
                        border-radius: 8px;
                        cursor: pointer;
                        font-weight: bold;
                    ">🗑️ Clear All Basketballs</button>
                </div>

                <!-- MATCH MODE SCOREBOARD -->
                <div id="match-scoreboard" style="
                    display: none;
                    background: rgba(0,0,0,0.4);
                    padding: 15px;
                    border-radius: 8px;
                    text-align: center;
                    margin-bottom: 15px;
                    border: 2px solid #ffd700;
                ">
                    <h4 style="margin: 0 0 10px 0; color: #ffd700; font-size: 14px;">🏀 NBA SCORE</h4>
                    <div style="display: flex; justify-content: space-between; font-size: 18px; font-weight: bold;">
                        <span>P1: <span id="score-p1" style="color: #ff6b6b;">0</span></span>
                        <span style="color: #666;">vs</span>
                        <span>P2: <span id="score-p2" style="color: #74b9ff;">0</span></span>
                    </div>
                </div>

                <!-- NBA COURT SPECS -->
                <div style="
                    background: rgba(210,105,30,0.2);
                    padding: 10px;
                    border-radius: 6px;
                    font-size: 10px;
                    margin-bottom: 15px;
                    border: 1px solid ${NBA_COURT_CONSTANTS.COURT_COLOR};
                ">
                    <div style="color: #FF8C00; font-weight: bold; margin-bottom: 8px; text-align: center;">🏀 NBA COURT SPECS</div>
                    <div style="line-height: 1.4; color: #FFE6D1;">
                        ✅ Official court dimensions<br>
                        🏀 3-point lines & free throw areas<br>
                        ⚪ Center circle & court lines<br>
                        🗼 Support poles with nets<br>
                        🏟️ Hardwood parquet floor
                    </div>
                </div>

                <!-- STATS -->
                <div id="stats" style="
                    background: rgba(0,0,0,0.3);
                    padding: 10px;
                    border-radius: 6px;
                    font-size: 10px;
                    text-align: center;
                    border: 1px solid rgba(255,140,0,0.3);
                ">
                    <div>Basketballs: <span id="object-count">0</span> | Baskets: <span id="goals-count">0</span></div>
                    <div>Collisions: <span id="collision-count">0</span> | Max Speed: <span id="max-speed">0</span></div>
                    <div>Queue: <span id="queue-count">0</span> | Performance: <span id="performance">Optimal</span></div>
                </div>

                <!-- HELP TEXT -->
                <div style="
                    text-align: center;
                    margin-top: 15px;
                    font-size: 9px;
                    color: rgba(255,255,255,0.6);
                    border-top: 1px solid rgba(255,255,255,0.1);
                    padding-top: 10px;
                ">
                    Professional NBA court with physics<br>
                    <span style="color: #FF8C00;">Possession system & official dimensions</span>
                </div>
            `;

            panel.appendChild(header);
            panel.appendChild(content);
            document.body.appendChild(panel);

            this.makePanelDraggable();
            this.setupPanelButtons();
            this.setupAdvancedEventListeners();
            this.startAdvancedStatsMonitoring();
        }

        setupAdvancedEventListeners() {
            // Court and physics controls
            document.getElementById('create-court-btn')?.addEventListener('click', () => this.createProfessionalNBACourt());
            document.getElementById('toggle-physics')?.addEventListener('click', () => this.togglePhysics());

            // Object creation
            document.getElementById('add-basketball-btn')?.addEventListener('click', () => this.addRandomBasketball());

            // Actions
            document.getElementById('reset-all-btn')?.addEventListener('click', () => this.resetAllObjects());
            document.getElementById('clear-all-btn')?.addEventListener('click', () => this.clearAllObjects());

            // Advanced controls
            document.getElementById('match-mode-toggle')?.addEventListener('click', () => this.toggleMatchMode());
            document.getElementById('clean-canvas-btn')?.addEventListener('click', () => this.cleanCanvas());

            // Physics mode selection
            document.getElementById('physics-mode')?.addEventListener('change', (e) => {
                this.controls.alternatePhysics = e.target.value;
                this.showFeedback(`🔬 Physics Mode: ${e.target.options[e.target.selectedIndex].text}`, '#FF8C00');
            });

            // Canvas click for basketball creation
            if (this.canvasElement) {
                this.canvasElement.addEventListener('click', (e) => this.createBasketball(e.clientX - this.canvasElement.getBoundingClientRect().left, e.clientY - this.canvasElement.getBoundingClientRect().top));
            }
        }

        /* ---------- NBA PIXEL TEXT DRAWING (CORREGIDO) ---------- */
        NBA_PIXEL_LETTERS = {
            'B': [[1,1,1,1],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,1,1,1]],
            'A': [[0,1,1,0],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,0,0,1]],
            'S': [[1,1,1,1],[1,0,0,0],[1,1,1,1],[0,0,0,1],[1,1,1,1]],
            'K': [[1,0,0,1],[1,0,1,0],[1,1,0,0],[1,0,1,0],[1,0,0,1]],
            'E': [[1,1,1,1],[1,0,0,0],[1,1,1,0],[1,0,0,0],[1,1,1,1]],
            'T': [[1,1,1,1,1],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0]],
            'L': [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,1,1,1]],
            'O': [[1,1,1,1],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,1,1,1]],
            'P': [[1,1,1,1],[1,0,0,1],[1,1,1,1],[1,0,0,0],[1,0,0,0]]
        };

        NUMBER_PATTERNS = {
            0: [[1,1,1],[1,0,1],[1,0,1],[1,0,1],[1,1,1]],
            1: [[0,1,0],[1,1,0],[0,1,0],[0,1,0],[1,1,1]],
            2: [[1,1,1],[0,0,1],[1,1,1],[1,0,0],[1,1,1]],
            3: [[1,1,1],[0,0,1],[1,1,1],[0,0,1],[1,1,1]],
            4: [[1,0,1],[1,0,1],[1,1,1],[0,0,1],[0,0,1]],
            5: [[1,1,1],[1,0,0],[1,1,1],[0,0,1],[1,1,1]]
        };

        // FUNCIÓN PRINCIPAL PARA DIBUJAR "BASKETBALL" (CORREGIDA)
        async drawNBAMainText(text, coords) {
            if (this.fieldDrawing.isStopped) return;

            const letterSpacing = coords.text.pixelSize * 7;
            const textWidth = text.length * letterSpacing;
            let currentX = coords.text.x - (textWidth / 2);

            for (let i = 0; i < text.length; i++) {
                if (this.fieldDrawing.isStopped) break;
                const letter = text[i].toUpperCase();
                if (letter === ' ') {
                    currentX += letterSpacing;
                    continue;
                }
                const pattern = this.NBA_PIXEL_LETTERS[letter];
                if (!pattern) continue;

                for (let row = 0; row < pattern.length; row++) {
                    for (let col = 0; col < pattern[row].length; col++) {
                        if (pattern[row][col] === 1) {
                            const pixelX = currentX + (col * coords.text.pixelSize);
                            const pixelY = coords.text.y + (row * coords.text.pixelSize);
                            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
                            if (pixelX >= 0 && pixelX < canvasSize.width && pixelY >= 0 && pixelY < canvasSize.height) {
                                await this.drawNBAPixel(pixelX, pixelY, NBA_COURT_CONSTANTS.TEXT_COLOR, coords.text.pixelSize);
                            }
                        }
                    }
                }
                currentX += letterSpacing;
                await sleep(120);
            }
        }

        // FUNCIÓN PARA TEXTOS PEQUEÑOS (SCOREBOARDS)
        async drawNBASmallText(text, x, y, color, pixelSize) {
            let currentX = x;
            for (let i = 0; i < text.length; i++) {
                const letter = text[i];
                const pattern = this.NBA_PIXEL_LETTERS[letter];
                if (pattern) {
                    for (let row = 0; row < pattern.length; row++) {
                        for (let col = 0; col < pattern[row].length; col++) {
                            if (pattern[row][col] === 1) {
                                const pixelX = currentX + (col * pixelSize);
                                const pixelY = y + (row * pixelSize);
                                await this.drawNBAPixel(pixelX, pixelY, color, pixelSize);
                            }
                        }
                    }
                }
                currentX += pixelSize * 4;
            }
        }

        // FUNCIÓN PARA NÚMEROS
        async drawPixelNumber(number, x, y, color, pixelSize) {
            const pattern = this.NUMBER_PATTERNS[number];
            if (!pattern) return;

            for (let row = 0; row < pattern.length; row++) {
                for (let col = 0; col < pattern[row].length; col++) {
                    if (pattern[row][col] === 1) {
                        const pixelX = x + (col * pixelSize);
                        const pixelY = y + (row * pixelSize);
                        await this.drawNBAPixel(pixelX, pixelY, color, pixelSize);
                    }
                }
            }
        }

        async drawNBAPixel(x, y, color, size = 2) {
            if (this.fieldDrawing.isStopped) return;
            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
            x = clamp(x, 0, canvasSize.width - size);
            y = clamp(y, 0, canvasSize.height - size);
            enqueueDrawCommand(x, y, x + 1, y + 1, color, size);
            await sleep(20);
        }


        /* ---------- PROFESSIONAL NBA COURT CREATION (from first script) ---------- */
        calculateProfessionalBasketballCoordinates() {
            const size = { width: drawariaCanvas.width, height: drawariaCanvas.height };
            return {
                // Aros de baloncesto con dimensiones profesionales
                leftBasket: {
                    x: Math.floor(size.width * 0.08),
                    y: Math.floor(size.height * 0.25),
                    rimWidth: Math.floor(size.width * 0.06),
                    rimHeight: Math.floor(size.height * 0.04),
                    backboardWidth: Math.floor(size.width * 0.1),
                    backboardHeight: Math.floor(size.height * 0.12)
                },
                rightBasket: {
                    x: Math.floor(size.width * 0.92),
                    y: Math.floor(size.height * 0.25),
                    rimWidth: Math.floor(size.width * 0.06),
                    rimHeight: Math.floor(size.height * 0.04),
                    backboardWidth: Math.floor(size.width * 0.1),
                    backboardHeight: Math.floor(size.height * 0.12)
                },
                // Líneas de la cancha
                centerLine: {
                    x: Math.floor(size.width * 0.5),
                    y1: Math.floor(size.height * 0.05),
                    y2: Math.floor(size.height * 0.95)
                },
                // Círculo central
                centerCircle: {
                    x: Math.floor(size.width * 0.5),
                    y: Math.floor(size.height * 0.5),
                    radius: Math.floor(size.width * 0.08)
                },
                // Líneas de tres puntos
                threePointLine: {
                    leftArc: {
                        centerX: Math.floor(size.width * 0.08),
                        centerY: Math.floor(size.height * 0.5),
                        radius: Math.floor(size.width * 0.18)
                    },
                    rightArc: {
                        centerX: Math.floor(size.width * 0.92),
                        centerY: Math.floor(size.height * 0.5),
                        radius: Math.floor(size.width * 0.18)
                    }
                },
                // Área restringida (key/paint)
                leftKey: {
                    x: Math.floor(size.width * 0.02),
                    y: Math.floor(size.height * 0.35),
                    width: Math.floor(size.width * 0.18),
                    height: Math.floor(size.height * 0.3)
                },
                rightKey: {
                    x: Math.floor(size.width * 0.8),
                    y: Math.floor(size.height * 0.35),
                    width: Math.floor(size.width * 0.18),
                    height: Math.floor(size.height * 0.3)
                },
                // Texto centrado
                text: {
                    x: Math.floor(size.width * 0.5),
                    y: Math.floor(size.height * 0.08),
                    pixelSize: Math.max(3, Math.floor(size.width * 0.006)) // Aumenté el tamaño mínimo
                }

            };
        }

        async createProfessionalNBACourt() {
            if (this.fieldDrawing.isDrawing) {
                this.showFeedback('⚠️ NBA Court creation already in progress!', '#ed8936');
                return;
            }
            if (!drawariaSocket || !drawariaCanvas || !drawariaCtx) {
                this.showFeedback('❌ Canvas or WebSocket connection not detected!', '#f56565');
                return;
            }

            this.fieldDrawing.isDrawing = true;
            this.fieldDrawing.isStopped = false;

            try {
                const coords = this.calculateProfessionalBasketballCoordinates();
                const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };

                this.showFeedback(`🏀 Creating Professional NBA Court: ${canvasSize.width}x${canvasSize.height}`, NBA_COURT_CONSTANTS.COURT_COLOR);
                await sleep(800);

                // === 1. PISO DE PARQUET ===
                this.showFeedback("🏀 PHASE 1: Hardwood parquet floor...", NBA_COURT_CONSTANTS.COURT_COLOR);
                await this.drawProfessionalBasketballFloor();
                await sleep(300);
                if (this.fieldDrawing.isStopped) return;

                // === 2. LÍNEAS OFICIALES ===
                this.showFeedback("⚪ PHASE 2: Official NBA court lines...", NBA_COURT_CONSTANTS.LINE_COLOR);
                await this.drawProfessionalCourtLines(coords);
                await sleep(300);
                if (this.fieldDrawing.isStopped) return;

                // === 3. AROS PROFESIONALES ===
                this.showFeedback("🏀 PHASE 3: Installing left NBA rim...", NBA_COURT_CONSTANTS.RIM_COLOR);
                await this.drawProfessionalBasketballRim(coords.leftBasket, 'left');
                this.showFeedback("🏀 PHASE 3: Installing right NBA rim...", NBA_COURT_CONSTANTS.RIM_COLOR);
                await this.drawProfessionalBasketballRim(coords.rightBasket, 'right');
                await sleep(300);
                if (this.fieldDrawing.isStopped) return;

                // === 4. TEXTO "BASKETBALL" ===
                this.showFeedback("🎮 PHASE 4: Drawing 'BASKETBALL' text...", NBA_COURT_CONSTANTS.TEXT_COLOR);
                await this.drawNBAMainText("BASKETBALL", coords);

                // === CANCHA COMPLETA ===
                this.showFeedback("🏆 PROFESSIONAL NBA COURT COMPLETE! 🏀🎯", "#006400");
                setTimeout(() => {
                    const statusDiv = document.querySelector('.feedback-div');
                    if (statusDiv) {
                        statusDiv.style.opacity = 0;
                        setTimeout(() => statusDiv.remove(), 500);
                    }
                }, 4000);

                // Si match mode está activo, configurar área de juego
                if (this.matchMode.active) {
                    this.setupReducedPlayArea();
                    await this.drawNBAScoreboards(coords);
                }

            } catch (error) {
                console.error("Error creating NBA court:", error);
                this.showFeedback(`❌ Error: ${error.message}`, "#B22222");
            } finally {
                this.fieldDrawing.isDrawing = false;
            }
        }

        // Piso de parquet profesional
        async drawProfessionalBasketballFloor() {
            if (this.fieldDrawing.isStopped) return;
            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };

            // Base de madera
            await this.drawLineLocalAndServer(0, canvasSize.height - 5, canvasSize.width, canvasSize.height - 5, NBA_COURT_CONSTANTS.COURT_COLOR, 8, 40);

            // Líneas de madera horizontales para simular tablones
            for (let y = 25; y < canvasSize.height - 10; y += 30) {
                await this.drawLineLocalAndServer(0, y, canvasSize.width, y, '#8B4513', 1, 20);
                if (this.fieldDrawing.isStopped) break;
            }
        }

        // Líneas oficiales de cancha NBA
        async drawProfessionalCourtLines(coords) {
            if (this.fieldDrawing.isStopped) return;
            const lineThickness = Math.max(4, Math.floor(drawariaCanvas.width * NBA_COURT_CONSTANTS.LINE_THICKNESS_MULTIPLIER));

            // Línea central
            await this.drawLineLocalAndServer(
                coords.centerLine.x, coords.centerLine.y1,
                coords.centerLine.x, coords.centerLine.y2,
                NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, 80
            );

            // Bordes de la cancha
            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
            await this.drawLineLocalAndServer(0, 0, canvasSize.width, 0, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, 60);
            await this.drawLineLocalAndServer(canvasSize.width, 0, canvasSize.width, canvasSize.height, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, 60);
            await this.drawLineLocalAndServer(canvasSize.width, canvasSize.height, 0, canvasSize.height, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, 60);
            await this.drawLineLocalAndServer(0, canvasSize.height, 0, 0, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, 60);

            // Círculo central
            await this.drawProfessionalCircle(
                coords.centerCircle.x,
                coords.centerCircle.y,
                coords.centerCircle.radius,
                NBA_COURT_CONSTANTS.LINE_COLOR,
                lineThickness
            );

            // Áreas restringidas
            await this.drawProfessionalRectangleOutline(coords.leftKey, NBA_COURT_CONSTANTS.KEY_COLOR, lineThickness);
            await this.drawProfessionalRectangleOutline(coords.rightKey, NBA_COURT_CONSTANTS.KEY_COLOR, lineThickness);

            // Líneas de tres puntos
            await this.drawProfessionalArc(coords.threePointLine.leftArc, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, Math.PI/4, 3*Math.PI/4);
            await this.drawProfessionalArc(coords.threePointLine.rightArc, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness, Math.PI/4, 3*Math.PI/4);

            // Líneas de tiro libre
            await this.drawProfessionalFreeThrowLines(coords, NBA_COURT_CONSTANTS.LINE_COLOR, lineThickness);
        }

        // Aros NBA con postes de soporte profesionales
        async drawProfessionalBasketballRim(basketCoords, side = 'left') {
            if (this.fieldDrawing.isStopped) return;

            // Tablero rectangular
            const boardX = basketCoords.x - basketCoords.backboardWidth/2;
            const boardY = basketCoords.y - basketCoords.backboardHeight/2;

            await this.drawProfessionalRectangleOutline({
                x: boardX,
                y: boardY,
                width: basketCoords.backboardWidth,
                height: basketCoords.backboardHeight
            }, NBA_COURT_CONSTANTS.BACKBOARD_COLOR, 5);

            // Relleno del tablero (líneas horizontales)
            for (let y = boardY + 5; y < boardY + basketCoords.backboardHeight - 5; y += 3) {
                await this.drawLineLocalAndServer(boardX + 5, y, boardX + basketCoords.backboardWidth - 5, y, NBA_COURT_CONSTANTS.BACKBOARD_COLOR, 1, 20);
                if (this.fieldDrawing.isStopped) break;
            }

            // === POSTE DE SOPORTE PROFESIONAL ===
            const poleWidth = Math.floor(basketCoords.backboardWidth * 0.15);
            const poleHeight = Math.floor(drawariaCanvas.height * 0.15);
            const poleX = basketCoords.x - poleWidth/2;
            const poleY = boardY + basketCoords.backboardHeight;

            this.showFeedback(`🏗️ Installing ${side} NBA support pole...`, NBA_COURT_CONSTANTS.POLE_COLOR);

            // Dibujar poste vertical
            await this.drawProfessionalRectangleOutline({
                x: poleX,
                y: poleY,
                width: poleWidth,
                height: poleHeight
            }, NBA_COURT_CONSTANTS.POLE_COLOR, 4);

            // Rellenar el poste con líneas verticales para textura metálica
            for (let x = poleX + 2; x < poleX + poleWidth - 2; x += 3) {
                await this.drawLineLocalAndServer(x, poleY + 2, x, poleY + poleHeight - 2, '#808080', 1, 15);
                if (this.fieldDrawing.isStopped) break;
            }

            // Aro circular NBA
            const rimY = basketCoords.y + basketCoords.backboardHeight/3;
            await this.drawProfessionalCircle(
                basketCoords.x,
                rimY,
                basketCoords.rimWidth/2,
                NBA_COURT_CONSTANTS.RIM_COLOR,
                6
            );

            // Red del aro (líneas colgantes)
            const netLines = 8; // Más líneas para red más realista
            for (let i = 0; i < netLines; i++) {
                const angle = (Math.PI * 2 * i) / netLines;
                const startX = basketCoords.x + Math.cos(angle) * (basketCoords.rimWidth/2);
                const startY = rimY;
                const endX = startX + Math.cos(angle) * 8;
                const endY = startY + 20;

                await this.drawLineLocalAndServer(startX, startY, endX, endY, NBA_COURT_CONSTANTS.NET_COLOR, 2, 35);
                if (this.fieldDrawing.isStopped) break;
            }
        }

        // === FUNCIONES AUXILIARES GEOMÉTRICAS PROFESIONALES ===
        async drawProfessionalCircle(centerX, centerY, radius, color, thickness) {
            const steps = 24;
            for (let i = 0; i <= steps; i++) {
                if (this.fieldDrawing.isStopped) break;
                const angle1 = (Math.PI * 2 * i) / steps;
                const angle2 = (Math.PI * 2 * (i + 1)) / steps;
                const x1 = centerX + Math.cos(angle1) * radius;
                const y1 = centerY + Math.sin(angle1) * radius;
                const x2 = centerX + Math.cos(angle2) * radius;
                const y2 = centerY + Math.sin(angle2) * radius;
                await this.drawLineLocalAndServer(x1, y1, x2, y2, color, thickness, 30);
            }
        }

        async drawProfessionalArc(arcCoords, color, thickness, startAngle = 0, endAngle = Math.PI) {
            const steps = 16;
            for (let i = 0; i < steps; i++) {
                if (this.fieldDrawing.isStopped) break;
                const progress1 = i / steps;
                const progress2 = (i + 1) / steps;
                const angle1 = startAngle + (endAngle - startAngle) * progress1;
                const angle2 = startAngle + (endAngle - startAngle) * progress2;
                const x1 = arcCoords.centerX + Math.cos(angle1) * arcCoords.radius;
                const y1 = arcCoords.centerY + Math.sin(angle1) * arcCoords.radius;
                const x2 = arcCoords.centerX + Math.cos(angle2) * arcCoords.radius;
                const y2 = arcCoords.centerY + Math.sin(angle2) * arcCoords.radius;
                await this.drawLineLocalAndServer(x1, y1, x2, y2, color, thickness, 40);
            }
        }

        async drawProfessionalRectangleOutline(rectCoords, color, thickness) {
            await this.drawLineLocalAndServer(rectCoords.x, rectCoords.y,
                rectCoords.x + rectCoords.width, rectCoords.y, color, thickness, 50);
            await this.drawLineLocalAndServer(rectCoords.x + rectCoords.width, rectCoords.y,
                rectCoords.x + rectCoords.width, rectCoords.y + rectCoords.height, color, thickness, 50);
            await this.drawLineLocalAndServer(rectCoords.x + rectCoords.width, rectCoords.y + rectCoords.height,
                rectCoords.x, rectCoords.y + rectCoords.height, color, thickness, 50);
            await this.drawLineLocalAndServer(rectCoords.x, rectCoords.y + rectCoords.height,
                rectCoords.x, rectCoords.y, color, thickness, 50);
        }

        async drawProfessionalFreeThrowLines(coords, color, thickness) {
            // Línea de tiro libre izquierda
            const freeThrowX = coords.leftKey.x + coords.leftKey.width;
            await this.drawLineLocalAndServer(
                freeThrowX, coords.leftKey.y,
                freeThrowX, coords.leftKey.y + coords.leftKey.height,
                color, thickness, 60
            );
            // Línea de tiro libre derecha
            await this.drawLineLocalAndServer(
                coords.rightKey.x, coords.rightKey.y,
                coords.rightKey.x, coords.rightKey.y + coords.rightKey.height,
                color, thickness, 60
            );
            // Semicírculos de tiro libre
            await this.drawProfessionalArc({
                centerX: freeThrowX,
                centerY: coords.leftKey.y + coords.leftKey.height/2,
                radius: coords.leftKey.height/2
            }, color, thickness, -Math.PI/2, Math.PI/2);
            await this.drawProfessionalArc({
                centerX: coords.rightKey.x,
                centerY: coords.rightKey.y + coords.rightKey.height/2,
                radius: coords.rightKey.height/2
            }, color, thickness, Math.PI/2, 3*Math.PI/2);
        }

        /* ---------- BASKETBALL POSSESSION SYSTEM ---------- */
        handleBasketballPossession() {
            const players = this.getPlayerPositions();
            if (players.length === 0) return;

            this.physicsObjects.forEach(ball => {
                if (ball.type !== 'basketball') return;

                let closestPlayer = null;
                let closestDistance = Infinity;

                // Encontrar jugador más cercano
                players.forEach(player => {
                    const dx = ball.x - player.x;
                    const dy = ball.y - player.y;
                    const distance = Math.sqrt(dx * dx + dy * dy);

                    if (distance < closestDistance) {
                        closestDistance = distance;
                        closestPlayer = player;
                    }
                });

                // Sistema de posesión
                if (closestPlayer && closestDistance < this.possessionSystem.possessionDistance) {
                    const currentTime = performance.now();

                    // Si no tiene dueño o es un robo válido
                    if (!ball.owner || (ball.owner.id !== closestPlayer.id &&
                        currentTime - ball.lastStealAttempt > PHYSICS_CONSTANTS.STEAL_COOLDOWN)) {

                        // Cambio de posesión
                        if (ball.owner && ball.owner.id !== closestPlayer.id) {
                            ball.lastStealAttempt = currentTime;
                            this.showFeedback(`🏀 ${closestPlayer.type === 'self' ? 'YOU' : 'OPPONENT'} STOLE THE BALL!`, '#FF4500');
                        }

                        ball.owner = closestPlayer;
                        ball.isBeingDribbled = true;
                    }

                    // Efecto de dribleo
                    if (ball.owner && ball.owner.id === closestPlayer.id) {
                        this.applyDribblePhysics(ball, closestPlayer);
                    }
                } else {
                    // Pelota libre
                    ball.owner = null;
                    ball.isBeingDribbled = false;
                }
            });
        }

        // Física de dribleo
        applyDribblePhysics(ball, player) {
            const dx = player.x - ball.x;
            const dy = player.y - ball.y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance > 0) {
                // Fuerza magnética suave hacia el jugador
                const magneticForce = PHYSICS_CONSTANTS.DRIBBLE_FORCE / (distance * 0.5);
                ball.vx += (dx / distance) * magneticForce * PHYSICS_CONSTANTS.TIMESTEP;
                ball.vy += (dy / distance) * magneticForce * PHYSICS_CONSTANTS.TIMESTEP;

                // Transferir velocidad del jugador
                if (player.vx || player.vy) {
                    ball.vx += (player.vx || 0) * 0.3;
                    ball.vy += (player.vy || 0) * 0.3;
                }

                // Dribleo automático cada 800ms
                if (performance.now() - ball.lastDribbleTime > 800) {
                    ball.lastDribbleTime = performance.now();
                    ball.vy -= 100; // Pequeño rebote hacia arriba
                }
            }
        }

        /* ---------- NBA SCORING SYSTEM ---------- */
        checkBasketballScoring() {
            if (!this.matchMode.active || !this.canvasElement) return;

            const coords = this.calculateProfessionalBasketballCoordinates();
            const currentTime = performance.now();

            this.physicsObjects.forEach(ball => {
                if (ball.type !== 'basketball') return;
                if (currentTime - ball.lastGoalTime < 2000) return;

                // Detección de canasta más precisa para aros NBA
                const basketDetection = PHYSICS_CONSTANTS.BALL_RADIUS + 15;

                // Canasta izquierda (P2 anota) - usando coordenadas del aro
                const leftRimY = coords.leftBasket.y + coords.leftBasket.backboardHeight/3;
                if (ball.x >= coords.leftBasket.x - basketDetection &&
                    ball.x <= coords.leftBasket.x + basketDetection &&
                    ball.y >= leftRimY - basketDetection &&
                    ball.y <= leftRimY + basketDetection) {

                    ball.lastGoalTime = currentTime;
                    this.scoreBasket('p2', ball);
                }

                // Canasta derecha (P1 anota) - usando coordenadas del aro
                const rightRimY = coords.rightBasket.y + coords.rightBasket.backboardHeight/3;
                if (ball.x >= coords.rightBasket.x - basketDetection &&
                    ball.x <= coords.rightBasket.x + basketDetection &&
                    ball.y >= rightRimY - basketDetection &&
                    ball.y <= rightRimY + basketDetection) {

                    ball.lastGoalTime = currentTime;
                    this.scoreBasket('p1', ball);
                }
            });
        }

        // Anotar canasta con rebote hacia adentro
        async scoreBasket(player, basketball) {
            if (this.matchMode.goalCooldown) return;
            this.matchMode.goalCooldown = true;

            // Rebote hacia adentro de la canasta
            const bounceForce = 80;
            basketball.vx *= -0.2;
            basketball.vy = -bounceForce;

            this.matchMode.scores[player]++;
            this.gameStats.totalBaskets++;

            this.updateScoreboard();
            await this.updateNBAScoreDisplay();

            this.showFeedback(`🏀 NBA BASKET! ${player.toUpperCase()} SCORES!`, '#FFD700');

            // NO eliminar la pelota, solo liberar posesión
            basketball.owner = null;
            basketball.isBeingDribbled = false;

            setTimeout(() => {
                this.matchMode.goalCooldown = false;
            }, 1500);

            if (this.matchMode.scores[player] >= MATCH_CONSTANTS.MAX_BASKETS) {
                await this.endMatch(player);
            }
        }

        /* ---------- MATCH MODE WITH NBA COURT ---------- */
        toggleMatchMode() {
            const button = document.getElementById('match-mode-toggle');
            const scoreboard = document.getElementById('match-scoreboard');

            this.matchMode.active = !this.matchMode.active;

            if (this.matchMode.active) {
                button.style.background = 'linear-gradient(135deg, #ffd700, #ffb347)';
                scoreboard.style.display = 'block';
                this.setupMatchMode();
                this.showFeedback('🏆 NBA MATCH MODE ACTIVATED!', '#ffd700');
            } else {
                button.style.background = 'linear-gradient(135deg, #444, #666)';
                scoreboard.style.display = 'none';
                this.resetMatch();
                this.showFeedback('🏆 Match Mode Deactivated', '#666');
            }
        }

        async setupMatchMode() {
            await this.createProfessionalNBACourt();
            this.matchMode.scores = { p1: 0, p2: 0 };
            this.updateScoreboard();
            this.setupReducedPlayArea();

            setTimeout(() => {
                this.addRandomBasketball(true);
            }, 500);
        }

        async drawNBAScoreboards(coords) {
            if (!this.canvasElement) return;

            // P1 scoreboard (cerca del aro derecho)
            const p1X = coords.rightBasket.x;
            const p1Y = coords.rightBasket.y - 60;

            // P2 scoreboard (cerca del aro izquierdo)
            const p2X = coords.leftBasket.x;
            const p2Y = coords.leftBasket.y - 60;

            await this.drawNBASmallText("P1", p1X - 20, p1Y - 30, NBA_COURT_CONSTANTS.TEXT_COLOR, 3);
            await this.drawNBASmallText("P2", p2X - 20, p2Y - 30, NBA_COURT_CONSTANTS.TEXT_COLOR, 3);

            this.matchMode.lastScorePositions = {
                p1: { x: p1X, y: p1Y },
                p2: { x: p2X, y: p2Y }
            };

            await this.updateNBAScoreDisplay();
        }

        async updateNBAScoreDisplay() {
            if (!this.matchMode.lastScorePositions.p1) return;

            const { p1, p2 } = this.matchMode.lastScorePositions;
            const pixelSize = 4;

            await this.clearScoreArea(p1.x, p1.y, pixelSize);
            await this.clearScoreArea(p2.x, p2.y, pixelSize);

            await this.drawPixelNumber(this.matchMode.scores.p1, p1.x, p1.y, NBA_COURT_CONSTANTS.TEXT_COLOR, pixelSize);
            await this.drawPixelNumber(this.matchMode.scores.p2, p2.x, p2.y, NBA_COURT_CONSTANTS.TEXT_COLOR, pixelSize);
        }

        /* ---------- PHYSICS ENGINE ---------- */
        togglePhysics() {
            const toggleBtn = document.getElementById('toggle-physics');
            if (!this.isActive) {
                this.startPhysics();
                if (toggleBtn) {
                    toggleBtn.textContent = '🛑 Stop Basketball Engine';
                    toggleBtn.style.background = 'linear-gradient(135deg, #f56565, #e53e3e)';
                }
            } else {
                this.stopPhysics();
                if (toggleBtn) {
                    toggleBtn.textContent = '🚀 Launch Basketball Engine';
                    toggleBtn.style.background = 'linear-gradient(135deg, #FF8C00, #FF6347)';
                }
            }
        }

        startPhysics() {
            if (this.isActive) return;
            this.isActive = true;
            this.startGameLoop();
            this.showFeedback('🚀 NBA Basketball Engine Started!', '#FF8C00');
        }

        stopPhysics() {
            this.isActive = false;
            this.showFeedback('🛑 Basketball Engine Stopped', '#f56565');
        }

        startGameLoop() {
            if (!this.isActive) return;
            const currentTime = performance.now();
            if (currentTime - this.lastRenderTime >= this.renderInterval) {
                this.updateAdvancedPhysics();
                this.renderOptimized();
                this.lastRenderTime = currentTime;
            }
            requestAnimationFrame(() => this.startGameLoop());
        }

        updateAdvancedPhysics() {
            const dt = PHYSICS_CONSTANTS.TIMESTEP;

            // Apply physics mode modifications
            let gravityMultiplier = 1;
            let airResistanceMultiplier = 1;

            switch(this.controls.alternatePhysics) {
                case 'moon':
                    gravityMultiplier = 0.16;
                    break;
                case 'underwater':
                    airResistanceMultiplier = 15;
                    gravityMultiplier = 0.3;
                    break;
                case 'magnetic':
                    break;
            }

            // Update all basketballs
            this.physicsObjects.forEach(obj => {
                // Apply air resistance
                obj.vx *= (1 - PHYSICS_CONSTANTS.AIR_RESISTANCE * airResistanceMultiplier * dt);
                obj.vy *= (1 - PHYSICS_CONSTANTS.AIR_RESISTANCE * airResistanceMultiplier * dt);

                // Apply gravity
                obj.vy += PHYSICS_CONSTANTS.GRAVITY * gravityMultiplier * dt;

                // Magnetic field effects
                if (this.controls.alternatePhysics === 'magnetic') {
                    this.physicsObjects.forEach(otherObj => {
                        if (otherObj.id !== obj.id) {
                            const dx = otherObj.x - obj.x;
                            const dy = otherObj.y - obj.y;
                            const distance = Math.sqrt(dx * dx + dy * dy);

                            if (distance > 0 && distance < 200) {
                                const magneticForce = 50 / (distance * distance);
                                const forceX = (dx / distance) * magneticForce;
                                const forceY = (dy / distance) * magneticForce;

                                obj.vx += forceX * dt;
                                obj.vy += forceY * dt;
                            }
                        }
                    });
                }

                // Update position
                obj.x += obj.vx * dt;
                obj.y += obj.vy * dt;

                // Boundary collisions
                this.handleBoundaryCollisions(obj);

                // Track maximum velocity
                const speed = Math.sqrt(obj.vx * obj.vx + obj.vy * obj.vy);
                if (speed > this.gameStats.maxVelocityReached) {
                    this.gameStats.maxVelocityReached = speed;
                }

                // Limit maximum velocity
                if (speed > PHYSICS_CONSTANTS.MAX_VELOCITY) {
                    obj.vx = (obj.vx / speed) * PHYSICS_CONSTANTS.MAX_VELOCITY;
                    obj.vy = (obj.vy / speed) * PHYSICS_CONSTANTS.MAX_VELOCITY;
                }
            });

            // Handle collisions
            this.handleObjectCollisions();
            this.handleBallPlayerCollisions();

            // Handle basketball possession system
            this.handleBasketballPossession();

            // Check for basketball scoring
            if (this.matchMode.active) {
                this.checkBasketballScoring();
            }
        }

        /* ---------- OBJECT CREATION ---------- */
        addRandomBasketball(spawnAtCenterForScore = false) {
            if (!this.canvasElement) return;

            let x, y;
            if (spawnAtCenterForScore) {
                x = this.canvasElement.width / 2;
                y = this.canvasElement.height / 2;
            } else {
                const padding = 100;
                x = Math.random() * (this.canvasElement.width - 2 * padding) + padding;
                y = Math.random() * (this.canvasElement.height * 0.4 - 2 * padding) + padding;
            }

            this.createBasketball(x, y);
        }

        createBasketball(x, y) {
            const id = `basketball_${this.objectIdCounter++}`;
            const ball = {
                id: id,
                type: 'basketball',
                x: x, y: y, vx: 0, vy: 0,
                radius: PHYSICS_CONSTANTS.BALL_RADIUS,
                color: PHYSICS_CONSTANTS.BALL_COLOR,
                mass: PHYSICS_CONSTANTS.BALL_MASS,
                restitution: PHYSICS_CONSTANTS.RESTITUTION_BALL,
                friction: PHYSICS_CONSTANTS.FRICTION_COURT,
                lastRenderX: -9999, lastRenderY: -9999,
                creationTime: performance.now(),
                lastCollisionTime: 0,
                lastGoalTime: 0,

                // Propiedades de baloncesto
                owner: null,
                lastDribbleTime: 0,
                isBeingDribbled: false,
                lastStealAttempt: 0
            };

            this.physicsObjects.set(id, ball);
            this.gameStats.objectsCreated++;
            return ball;
        }

        /* ---------- COLLISION HANDLING ---------- */
        handleBoundaryCollisions(obj) {
            if (!this.canvasElement) return;

            let objHalfSize = obj.radius;

            let boundaries;
            if (this.matchMode.active && this.matchMode.playArea) {
                boundaries = {
                    left: this.matchMode.playArea.left + objHalfSize,
                    right: this.matchMode.playArea.right - objHalfSize,
                    top: this.matchMode.playArea.top + objHalfSize,
                    bottom: this.matchMode.playArea.bottom - objHalfSize
                };
            } else {
                boundaries = {
                    left: objHalfSize,
                    right: this.canvasElement.width - objHalfSize,
                    top: objHalfSize,
                    bottom: this.canvasElement.height - objHalfSize
                };
            }

            if (obj.x < boundaries.left) {
                obj.x = boundaries.left;
                obj.vx = -obj.vx * PHYSICS_CONSTANTS.RESTITUTION_WALL;
            } else if (obj.x > boundaries.right) {
                obj.x = boundaries.right;
                obj.vx = -obj.vx * PHYSICS_CONSTANTS.RESTITUTION_WALL;
            }

            if (obj.y < boundaries.top) {
                obj.y = boundaries.top;
                obj.vy = -obj.vy * PHYSICS_CONSTANTS.RESTITUTION_WALL;
            } else if (obj.y > boundaries.bottom) {
                obj.y = boundaries.bottom;
                obj.vy = -obj.vy * PHYSICS_CONSTANTS.RESTITUTION_WALL;
                obj.vx *= obj.friction;
            }
        }

        handleObjectCollisions() {
            const objectsArray = Array.from(this.physicsObjects.values());
            for (let i = 0; i < objectsArray.length; i++) {
                const objA = objectsArray[i];
                for (let j = i + 1; j < objectsArray.length; j++) {
                    const objB = objectsArray[j];

                    if (objA.type === 'basketball' && objB.type === 'basketball') {
                        if (this.handleBasketballCollision(objA, objB)) {
                            this.gameStats.totalCollisions++;
                            objA.lastCollisionTime = performance.now();
                            objB.lastCollisionTime = performance.now();
                        }
                    }
                }
            }
        }

        handleBasketballCollision(ball1, ball2) {
            const dx = ball2.x - ball1.x;
            const dy = ball2.y - ball1.y;
            const distance = Math.sqrt(dx * dx + dy * dy);
            const minDistance = ball1.radius + ball2.radius;

            if (distance < minDistance && distance !== 0) {
                const normalX = dx / distance;
                const normalY = dy / distance;

                const overlap = minDistance - distance;
                ball1.x -= normalX * overlap * 0.5;
                ball1.y -= normalY * overlap * 0.5;
                ball2.x += normalX * overlap * 0.5;
                ball2.y += normalY * overlap * 0.5;

                const rvX = ball2.vx - ball1.vx;
                const rvY = ball2.vy - ball1.vy;
                const velAlongNormal = rvX * normalX + rvY * normalY;

                if (velAlongNormal > 0) return false;

                const e = (ball1.restitution + ball2.restitution) * 0.5;
                let j = -(1 + e) * velAlongNormal;
                j /= (1 / ball1.mass) + (1 / ball2.mass);

                const impulseX = j * normalX;
                const impulseY = j * normalY;

                ball1.vx -= impulseX / ball1.mass;
                ball1.vy -= impulseY / ball1.mass;
                ball2.vx += impulseX / ball2.mass;
                ball2.vy += impulseY / ball2.mass;

                return true;
            }
            return false;
        }

        /* ---------- PLAYER COLLISION SYSTEM ---------- */
        getPlayerPositions() {
            const currentTime = performance.now();
            const players = [];
            if (!drawariaCanvas) return players;

            const canvasRect = drawariaCanvas.getBoundingClientRect();
            const deltaTime = currentTime - this.playerTracker.lastUpdateTime;

            const selfPlayer = document.querySelector('div.spawnedavatar.spawnedavatar-self');
            if (selfPlayer) {
                const rect = selfPlayer.getBoundingClientRect();
                const currentPos = {
                    type: 'self',
                    id: selfPlayer.dataset.playerid || 'self',
                    x: rect.left - canvasRect.left + rect.width / 2,
                    y: rect.top - canvasRect.top + rect.height / 2,
                    width: rect.width,
                    height: rect.height,
                    radius: Math.max(rect.width, rect.height) / 2,
                    vx: 0,
                    vy: 0
                };

                const prevPlayer = this.playerTracker.players.get('self');
                if (prevPlayer && deltaTime > 0) {
                    currentPos.vx = (currentPos.x - prevPlayer.x) / (deltaTime / 1000);
                    currentPos.vy = (currentPos.y - prevPlayer.y) / (deltaTime / 1000);
                }

                players.push(currentPos);
                this.playerTracker.players.set('self', currentPos);
            }

            const otherPlayers = document.querySelectorAll('div.spawnedavatar.spawnedavatar-otherplayer');
            otherPlayers.forEach((player, index) => {
                const rect = player.getBoundingClientRect();
                const playerId = player.dataset.playerid || `other_${index}`;
                const currentPos = {
                    type: 'other',
                    id: playerId,
                    x: rect.left - canvasRect.left + rect.width / 2,
                    y: rect.top - canvasRect.top + rect.height / 2,
                    width: rect.width,
                    height: rect.height,
                    radius: Math.max(rect.width, rect.height) / 2,
                    vx: 0,
                    vy: 0
                };

                const prevPlayer = this.playerTracker.players.get(playerId);
                if (prevPlayer && deltaTime > 0) {
                    currentPos.vx = (currentPos.x - prevPlayer.x) / (deltaTime / 1000);
                    currentPos.vy = (currentPos.y - prevPlayer.y) / (deltaTime / 1000);
                }

                players.push(currentPos);
                this.playerTracker.players.set(playerId, currentPos);
            });

            this.playerTracker.lastUpdateTime = currentTime;

            return players.filter(p =>
                p.x >= -this.playerTracker.detectionRadius &&
                p.x <= drawariaCanvas.width + this.playerTracker.detectionRadius &&
                p.y >= -this.playerTracker.detectionRadius &&
                p.y <= drawariaCanvas.height + this.playerTracker.detectionRadius
            );
        }

        handleBallPlayerCollisions() {
            const players = this.getPlayerPositions();
            if (players.length === 0) return;

            this.physicsObjects.forEach(ball => {
                if (ball.type !== 'basketball') return;

                players.forEach(player => {
                    const dx = ball.x - player.x;
                    const dy = ball.y - player.y;
                    const distance = Math.sqrt(dx * dx + dy * dy);
                    const detectionDistance = this.playerTracker.detectionRadius;

                    if (distance < detectionDistance && distance > 0) {
                        const intensity = Math.max(0, (detectionDistance - distance) / detectionDistance);

                        if (distance < ball.radius + player.radius) {
                            this.resolveBasketballPlayerCollision(ball, player, dx, dy, distance, 'collision');
                        } else if (intensity > 0.3) {
                            this.resolveBasketballPlayerCollision(ball, player, dx, dy, distance, 'push', intensity);
                        }
                    }
                });
            });
        }

        resolveBasketballPlayerCollision(ball, player, dx, dy, distance, interactionType = 'collision', intensity = 1.0) {
            const normalX = dx / distance;
            const normalY = dy / distance;

            if (interactionType === 'collision') {
                const overlap = (ball.radius + player.radius) - distance;
                ball.x += normalX * overlap * 1.1;
                ball.y += normalY * overlap * 1.1;

                const relativeVelX = ball.vx - (player.vx || 0);
                const relativeVelY = ball.vy - (player.vy || 0);
                const velAlongNormal = relativeVelX * normalX + relativeVelY * normalY;

                if (velAlongNormal > 0) return;

                const restitution = PHYSICS_CONSTANTS.PLAYER_RESTITUTION;
                const impulse = -(1 + restitution) * velAlongNormal;

                ball.vx += impulse * normalX;
                ball.vy += impulse * normalY;

                if (player.vx || player.vy) {
                    const transferFactor = 0.7;
                    ball.vx += (player.vx || 0) * transferFactor;
                    ball.vy += (player.vy || 0) * transferFactor;
                }

                const additionalForce = PHYSICS_CONSTANTS.PLAYER_INTERACTION_FORCE * 1.5;
                ball.vx += normalX * additionalForce * PHYSICS_CONSTANTS.TIMESTEP;
                ball.vy += normalY * additionalForce * PHYSICS_CONSTANTS.TIMESTEP;

            } else if (interactionType === 'push') {
                const pushForce = PHYSICS_CONSTANTS.PLAYER_INTERACTION_FORCE *
                                 PHYSICS_CONSTANTS.PLAYER_PUSH_MULTIPLIER *
                                 intensity * intensity;

                ball.vx += normalX * pushForce * PHYSICS_CONSTANTS.TIMESTEP;
                ball.vy += normalY * pushForce * PHYSICS_CONSTANTS.TIMESTEP;

                if (player.vx || player.vy) {
                    const playerSpeed = Math.sqrt((player.vx || 0) ** 2 + (player.vy || 0) ** 2);
                    if (playerSpeed > 50) {
                        const moveTransfer = intensity * 0.4;
                        ball.vx += (player.vx || 0) * moveTransfer;
                        ball.vy += (player.vy || 0) * moveTransfer;
                    }
                }
            }

            const maxSpeed = PHYSICS_CONSTANTS.MAX_VELOCITY * 1.2;
            const currentSpeed = Math.sqrt(ball.vx ** 2 + ball.vy ** 2);
            if (currentSpeed > maxSpeed) {
                ball.vx = (ball.vx / currentSpeed) * maxSpeed;
                ball.vy = (ball.vy / currentSpeed) * maxSpeed;
            }
        }

        /* ---------- RENDERING ---------- */
        renderOptimized() {
            this.physicsObjects.forEach(obj => {
                if (obj.type !== 'basketball') return;

                const dx = Math.abs(obj.x - obj.lastRenderX);
                const dy = Math.abs(obj.y - obj.lastRenderY);

                const needsServerRedraw = dx > MOVEMENT_THRESHOLD || dy > MOVEMENT_THRESHOLD;

                if (needsServerRedraw) {
                    // Erase old position
                    if (obj.lastRenderX !== -9999 || obj.lastRenderY !== -9999) {
                        this.drawBasketball(obj.lastRenderX, obj.lastRenderY, obj.radius, '#FFFFFF');
                    }

                    // Draw at new position
                    this.drawBasketball(obj.x, obj.y, obj.radius, obj.color);

                    obj.lastRenderX = obj.x;
                    obj.lastRenderY = obj.y;
                }
            });
        }

        drawBasketball(x, y, radius, color) {
            const effectiveThickness = radius * 2.5;
            enqueueDrawCommand(x, y, x + 0.1, y + 0.1, color, effectiveThickness);
        }

        /* ---------- UTILITY FUNCTIONS ---------- */
        clearAllObjects(showFeedback = true) {
            this.physicsObjects.clear();
            positionCache.clear();

            if (drawariaCtx && drawariaCanvas) {
                drawariaCtx.clearRect(0, 0, drawariaCanvas.width, drawariaCanvas.height);
            }
            if (showFeedback) {
                this.showFeedback('🗑️ ALL BASKETBALLS CLEARED!', '#cc0000');
            }
        }

        resetAllObjects() {
            if (this.canvasElement) {
                this.physicsObjects.forEach(obj => {
                    obj.x = this.canvasElement.width / 2 + (Math.random() - 0.5) * 100;
                    obj.y = this.canvasElement.height / 2 + (Math.random() - 0.5) * 100;
                    obj.vx = 0; obj.vy = 0;
                    obj.lastRenderX = -9999; obj.lastRenderY = -9999;
                    obj.lastGoalTime = 0;
                    obj.owner = null;
                    obj.isBeingDribbled = false;
                });

                this.showFeedback('🔄 All basketballs reset!', '#74b9ff');
            }
        }

        setupReducedPlayArea() {
            if (!this.canvasElement) return;

            const reductionSides = this.canvasElement.width * MATCH_CONSTANTS.PLAY_AREA_REDUCTION.SIDES;
            const reductionTop = this.canvasElement.height * MATCH_CONSTANTS.PLAY_AREA_REDUCTION.TOP;

            this.matchMode.playArea = {
                left: reductionSides,
                right: this.canvasElement.width - reductionSides,
                top: reductionTop,
                bottom: this.canvasElement.height
            };
        }

        updateScoreboard() {
            document.getElementById('score-p1').textContent = this.matchMode.scores.p1;
            document.getElementById('score-p2').textContent = this.matchMode.scores.p2;
        }

                async endMatch(winner) {
            this.showFeedback(`🏆 ${winner.toUpperCase()} WINS THE NBA MATCH!`, '#ffd700');

            setTimeout(() => {
                this.resetMatch();
            }, 3000);
        }

        resetMatch() {
            this.matchMode.scores = { p1: 0, p2: 0 };
            this.updateScoreboard();
            if (this.matchMode.active) {
                this.clearAllObjects(false);
                this.createProfessionalNBACourt().then(() => {
                    this.addRandomBasketball(true);
                });
            }
        }

        /* ---------- NBA PIXEL TEXT DRAWING ---------- */
        NBA_PIXEL_LETTERS = {
            'B': [[1,1,1,1],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,1,1,1]],
            'A': [[0,1,1,0],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,0,0,1]],
            'S': [[1,1,1,1],[1,0,0,0],[1,1,1,1],[0,0,0,1],[1,1,1,1]],
            'K': [[1,0,0,1],[1,0,1,0],[1,1,0,0],[1,0,1,0],[1,0,0,1]],
            'E': [[1,1,1,1],[1,0,0,0],[1,1,1,0],[1,0,0,0],[1,1,1,1]],
            'T': [[1,1,1,1,1],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0],[0,0,1,0,0]],
            'L': [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,1,1,1]],
            'O': [[1,1,1,1],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,1,1,1]],
            'P': [[1,1,1,1],[1,0,0,1],[1,1,1,1],[1,0,0,0],[1,0,0,0]],
            '1': [[0,1,0],[1,1,0],[0,1,0],[0,1,0],[1,1,1]],
            '2': [[1,1,1],[0,0,1],[1,1,1],[1,0,0],[1,1,1]]
        };

        NUMBER_PATTERNS = {
            0: [[1,1,1],[1,0,1],[1,0,1],[1,0,1],[1,1,1]],
            1: [[0,1,0],[1,1,0],[0,1,0],[0,1,0],[1,1,1]],
            2: [[1,1,1],[0,0,1],[1,1,1],[1,0,0],[1,1,1]],
            3: [[1,1,1],[0,0,1],[1,1,1],[0,0,1],[1,1,1]],
            4: [[1,0,1],[1,0,1],[1,1,1],[0,0,1],[0,0,1]],
            5: [[1,1,1],[1,0,0],[1,1,1],[0,0,1],[1,1,1]]
        };

        async drawNBAPixelText(text, coords) {
            if (this.fieldDrawing.isStopped) return;
            const letterSpacing = coords.text.pixelSize * 7;
            const textWidth = text.length * letterSpacing;
            let currentX = coords.text.x - (textWidth / 2);

            for (let i = 0; i < text.length; i++) {
                if (this.fieldDrawing.isStopped) break;
                const letter = text[i].toUpperCase();
                if (letter === ' ') {
                    currentX += letterSpacing;
                    continue;
                }
                const pattern = this.NBA_PIXEL_LETTERS[letter];
                if (!pattern) continue;

                for (let row = 0; row < pattern.length; row++) {
                    for (let col = 0; col < pattern[row].length; col++) {
                        if (pattern[row][col] === 1) {
                            const pixelX = currentX + (col * coords.text.pixelSize);
                            const pixelY = coords.text.y + (row * coords.text.pixelSize);
                            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
                            if (pixelX >= 0 && pixelX < canvasSize.width && pixelY >= 0 && pixelY < canvasSize.height) {
                                await this.drawNBAPixel(pixelX, pixelY, NBA_COURT_CONSTANTS.TEXT_COLOR, coords.text.pixelSize);
                            }
                        }
                    }
                }
                currentX += letterSpacing;
                await sleep(120);
            }
        }

        async drawNBAPixelText(text, x, y, color, pixelSize) {
            let currentX = x;
            for (let i = 0; i < text.length; i++) {
                const letter = text[i];
                const pattern = this.NBA_PIXEL_LETTERS[letter];
                if (pattern) {
                    for (let row = 0; row < pattern.length; row++) {
                        for (let col = 0; col < pattern[row].length; col++) {
                            if (pattern[row][col] === 1) {
                                const pixelX = currentX + (col * pixelSize);
                                const pixelY = y + (row * pixelSize);
                                await this.drawNBAPixel(pixelX, pixelY, color, pixelSize);
                            }
                        }
                    }
                }
                currentX += pixelSize * 4;
            }
        }

        async drawPixelNumber(number, x, y, color, pixelSize) {
            const pattern = this.NUMBER_PATTERNS[number];
            if (!pattern) return;

            for (let row = 0; row < pattern.length; row++) {
                for (let col = 0; col < pattern[row].length; col++) {
                    if (pattern[row][col] === 1) {
                        const pixelX = x + (col * pixelSize);
                        const pixelY = y + (row * pixelSize);
                        await this.drawNBAPixel(pixelX, pixelY, color, pixelSize);
                    }
                }
            }
        }

        async drawNBAPixel(x, y, color, size = 2) {
            if (this.fieldDrawing.isStopped) return;
            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
            x = clamp(x, 0, canvasSize.width - size);
            y = clamp(y, 0, canvasSize.height - size);
            enqueueDrawCommand(x, y, x + 1, y + 1, color, size);
            await sleep(20);
        }

        async clearScoreArea(x, y, size) {
            const clearWidth = size * 5 + 10;
            const clearHeight = size * 7 + 10;
            const startX = x - 5;
            const startY = y - 5;

            await sleep(10);
        }

        /* ---------- DRAWING FUNCTIONS ---------- */
        async drawLineLocalAndServer(startX, startY, endX, endY, color, thickness, delay = 60) {
            if (this.fieldDrawing.isStopped) {
                this.fieldDrawing.isDrawing = false;
                return;
            }
            const canvasSize = { width: drawariaCanvas.width, height: drawariaCanvas.height };
            startX = clamp(startX, -100, canvasSize.width + 100);
            startY = clamp(startY, 0, canvasSize.height);
            endX = clamp(endX, -100, canvasSize.width + 100);
            endY = clamp(endY, 0, canvasSize.height);
            enqueueDrawCommand(startX, startY, endX, endY, color, thickness);
            await sleep(delay);
        }

        // Clean Canvas functionality
        async cleanCanvas() {
            if (!drawariaCanvas) return;

            this.showFeedback('🧹 Cleaning NBA Court...', '#e17055');

            const canvasWidth = drawariaCanvas.width;
            const canvasHeight = drawariaCanvas.height;

            for (let y = 0; y < canvasHeight; y += 100) {
                for (let x = 0; x < canvasWidth; x += 100) {
                    const width = Math.min(100, canvasWidth - x);
                    const height = Math.min(100, canvasHeight - y);
                    enqueueDrawCommand(x, y, x + width, y + height, '#FFFFFF', Math.max(width, height));
                    await sleep(5);
                }
            }

            if (drawariaCtx) {
                drawariaCtx.clearRect(0, 0, canvasWidth, canvasHeight);
            }

            this.showFeedback('🧹 NBA Court Cleaned!', '#00d084');
        }

        /* ---------- PANEL FUNCTIONALITY ---------- */
        makePanelDraggable() {
            const panel = document.getElementById('advanced-physics-panel');
            const header = document.getElementById('panel-header');

            let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

            if (header) {
                header.onmousedown = dragMouseDown;
            } else {
                panel.onmousedown = dragMouseDown;
            }

            function dragMouseDown(e) {
                e = e || window.event;
                e.preventDefault();
                pos3 = e.clientX;
                pos4 = e.clientY;
                document.onmouseup = closeDragElement;
                document.onmousemove = elementDrag;
                panel.classList.add('panel-dragging');
            }

            function elementDrag(e) {
                e = e || window.event;
                e.preventDefault();
                pos1 = pos3 - e.clientX;
                pos2 = pos4 - e.clientY;
                pos3 = e.clientX;
                pos4 = e.clientY;

                const newTop = panel.offsetTop - pos2;
                const newLeft = panel.offsetLeft - pos1;

                const maxLeft = window.innerWidth - panel.offsetWidth;
                const maxTop = window.innerHeight - panel.offsetHeight;

                panel.style.top = Math.min(Math.max(0, newTop), maxTop) + "px";
                panel.style.left = Math.min(Math.max(0, newLeft), maxLeft) + "px";
                panel.style.right = 'auto';
            }

            function closeDragElement() {
                document.onmouseup = null;
                document.onmousemove = null;
                panel.classList.remove('panel-dragging');
            }
        }

        setupPanelButtons() {
            const minimizeBtn = document.getElementById('minimize-btn');
            const closeBtn = document.getElementById('close-btn');
            const content = document.getElementById('panel-content');
            const panel = document.getElementById('advanced-physics-panel');

            let isMinimized = false;

            // BOTÓN MINIMIZAR
            minimizeBtn?.addEventListener('click', (e) => {
                e.stopPropagation();
                if (!panel) return;

                if (!isMinimized) {
                    content.style.display = 'none';
                    panel.style.height = 'auto';
                    minimizeBtn.innerHTML = '+';
                    isMinimized = true;
                    this.showFeedback('📱 NBA Panel Minimized', '#FF8C00');
                } else {
                    content.style.display = 'block';
                    panel.style.height = 'auto';
                    minimizeBtn.innerHTML = '−';
                    isMinimized = false;
                    this.showFeedback('📱 NBA Panel Restored', '#FF8C00');
                }
            });

            // BOTÓN CERRAR
            closeBtn?.addEventListener('click', (e) => {
                e.stopPropagation();
                if (!panel) return;

                if (confirm('¿Estás seguro de que quieres cerrar el panel de baloncesto NBA?')) {
                    if (this.isActive) {
                        this.stopPhysics();
                    }
                    panel.remove();
                    this.showFeedback('❌ NBA Basketball Panel Closed', '#ff4757');
                    console.log('🔴 NBA Basketball Panel closed by user');
                }
            });

            // Efectos hover
            [minimizeBtn, closeBtn].forEach(btn => {
                if (!btn) return;
                btn.addEventListener('mouseenter', () => btn.style.opacity = '0.8');
                btn.addEventListener('mouseleave', () => btn.style.opacity = '1');
            });
        }

        startAdvancedStatsMonitoring() {
            setInterval(() => {
                document.getElementById('object-count').textContent = this.physicsObjects.size;
                document.getElementById('goals-count').textContent = this.gameStats.totalBaskets;
                document.getElementById('collision-count').textContent = this.gameStats.totalCollisions;
                document.getElementById('max-speed').textContent = Math.round(this.gameStats.maxVelocityReached);
                document.getElementById('queue-count').textContent = commandQueue.length;

                const queueSize = commandQueue.length;
                const performanceElement = document.getElementById('performance');
                if (queueSize < 30) {
                    performanceElement.textContent = 'Optimal';
                    performanceElement.style.color = '#48bb78';
                } else if (queueSize < 150) {
                    performanceElement.textContent = 'Good';
                    performanceElement.style.color = '#ed8936';
                } else {
                    performanceElement.textContent = 'Overloaded';
                    performanceElement.style.color = '#f56565';
                }
            }, 1000);
        }

        showFeedback(message, color) {
            // Remove existing feedback
            const existingFeedback = document.querySelector('.feedback-div');
            if (existingFeedback) existingFeedback.remove();

            const feedback = document.createElement('div');
            feedback.className = 'feedback-div';
            feedback.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: ${color};
                color: white;
                padding: 15px 25px;
                border-radius: 10px;
                font-weight: bold;
                z-index: 2147483648;
                font-size: 16px;
                box-shadow: 0 4px 20px rgba(0,0,0,0.3);
                opacity: 0;
                transition: opacity 0.3s ease-in-out;
                text-align: center;
                min-width: 300px;
                border: 2px solid rgba(255,255,255,0.3);
            `;
            feedback.innerHTML = message;

            document.body.appendChild(feedback);
            setTimeout(() => feedback.style.opacity = '1', 10);
            setTimeout(() => feedback.style.opacity = '0', 2500);
            setTimeout(() => feedback.remove(), 2800);
        }
    }

    /* ---------- GLOBAL INITIALIZATION ---------- */
    let basketballEngine = null;

    const initNBABasketballEngine = () => {
        if (!basketballEngine) {
            console.log('🏀 Initializing Advanced NBA Basketball Physics Engine v6.1...');
            basketballEngine = new AdvancedDrawariaBasketball();

            setTimeout(() => {
                const confirmMsg = document.createElement('div');
                confirmMsg.style.cssText = `
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    background: linear-gradient(45deg, #FF8C00, #FF6347);
                    color: white;
                    padding: 25px 35px;
                    border-radius: 20px;
                    font-size: 18px;
                    font-weight: bold;
                    z-index: 2147483648;
                    text-align: center;
                    box-shadow: 0 0 40px rgba(255,140,0,0.6);
                    opacity: 0;
                    transition: opacity 0.3s ease-in-out;
                    border: 3px solid #FFD700;
                `;
                confirmMsg.innerHTML = `
                    🏀 NBA BASKETBALL ENGINE v6.1 LOADED! 🏀<br>
                    <div style="font-size: 14px; margin-top: 10px; color: #FFE6D1;">
                        ✅ Professional NBA Court<br>
                        🏀 Advanced Physics System<br>
                        🎯 Match Mode & Possession<br>
                        🏗️ Support Poles & Official Lines<br>
                        🏆 Complete Scoring System
                    </div>
                `;

                document.body.appendChild(confirmMsg);
                setTimeout(() => confirmMsg.style.opacity = '1', 10);
                setTimeout(() => confirmMsg.style.opacity = '0', 4000);
                setTimeout(() => confirmMsg.remove(), 4300);
            }, 1000);
        }
    };

    // Enhanced CSS animations for NBA basketball
    const nbaBasketballStyle = document.createElement('style');
    nbaBasketballStyle.textContent = `
        @keyframes nba-bounce-effect {
            0% { transform: scale(0) rotate(0deg); opacity: 1; }
            50% { transform: scale(1.2) rotate(180deg); opacity: 0.8; }
            100% { transform: scale(0) rotate(360deg); opacity: 0; }
        }

        @keyframes nba-pulse-effect {
            0% { transform: scale(0.5); opacity: 0.8; }
            50% { transform: scale(1.3); opacity: 0.6; }
            100% { transform: scale(0); opacity: 0; }
        }

        @keyframes nba-dribble {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }

        .toggle-btn[data-active="true"] {
            box-shadow: 0 0 15px rgba(255, 140, 0, 0.6) !important;
        }

        .mode-toggle[data-active="true"] {
            box-shadow: 0 0 15px rgba(255, 215, 0, 0.8) !important;
        }

        #advanced-physics-panel {
            transition: none !important;
        }

        #panel-header:hover {
            background: linear-gradient(45deg, #FF6347, #FF4500) !important;
        }

        #minimize-btn:hover {
            background: rgba(255,255,255,0.4) !important;
        }

        #close-btn:hover {
            background: rgba(255,0,0,0.8) !important;
        }

        .panel-dragging {
            user-select: none !important;
            pointer-events: none !important;
            opacity: 0.9;
        }

        /* NBA court styling */
        .nba-basketball-court {
            background: linear-gradient(45deg, ${NBA_COURT_CONSTANTS.COURT_COLOR}, #CD853F);
        }

        .basketball-possession {
            animation: nba-dribble 0.8s infinite ease-in-out;
        }

        /* NBA match mode styling */
        .nba-match-active {
            box-shadow: 0 0 20px rgba(255, 215, 0, 0.5);
        }

        /* NBA scoring animation */
        .nba-score-animation {
            animation: nba-pulse-effect 2s ease-out;
        }

        /* Professional NBA panel styling */
        .nba-professional-panel {
            background: linear-gradient(135deg, #0f0f23, #1a1a3a, #2a1810);
            border: 3px solid ${NBA_COURT_CONSTANTS.COURT_COLOR};
        }
    `;
    document.head.appendChild(nbaBasketballStyle);

    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initNBABasketballEngine);
    } else {
        initNBABasketballEngine();
    }

    // Backup initialization
    setTimeout(initNBABasketballEngine, 2000);

    // Console welcome message
    console.log(`
    🏀============================================🏀
    🏆    NBA BASKETBALL PHYSICS ENGINE v6.1    🏆
    🏀============================================🏀

    ✅ Professional NBA Court Creation
    🏀 Advanced Physics System
    🎯 Match Mode with Scoring
    🏗️ Support Poles & Official Lines
    🏆 Complete Possession System

    Ready to play! Click the 🏀 button to start.
    🏀============================================🏀
    `);

})();