import React, { useState, useEffect, useRef } from 'react'; import { User, Zap, Star, Award, Heart, Trophy, Clock } from 'lucide-react'; export default function BasketballHeroes() { const [gameState, setGameState] = useState('start'); // start, playing, gameOver const [character, setCharacter] = useState(null); // 'kanye', 'hitler' const [teammate, setTeammate] = useState(null); const [score, setScore] = useState({ player: 0, ai: 0 }); const [possession, setPossession] = useState('player'); // 'player' or 'ai' const [ballPosition, setBallPosition] = useState({ x: 50, y: 50, progress: 0 }); const [playerPosition, setPlayerPosition] = useState({ x: 70, y: 70 }); const [teammatePosition, setTeammatePosition] = useState({ x: 30, y: 70 }); const [aiPosition, setAiPosition] = useState({ x: 50, y: 30 }); const [aiTeammatePosition, setAiTeammatePosition] = useState({ x: 70, y: 30 }); const [gameTime, setGameTime] = useState(60); // 60 seconds game const [shotClock, setShotClock] = useState(24); const [isShooting, setIsShooting] = useState(false); const [shootingPower, setShootingPower] = useState(0); const [messages, setMessages] = useState([]); const [specialMeter, setSpecialMeter] = useState(0); const [isSpecialActive, setIsSpecialActive] = useState(false); const [gameSpeed, setGameSpeed] = useState(1); const [difficulty, setDifficulty] = useState('normal'); const gameAreaRef = useRef(null); const animationFrameRef = useRef(null); const lastUpdateTimeRef = useRef(Date.now()); // Game constants const COURT_WIDTH = 100; const COURT_HEIGHT = 100; const PLAYER_SIZE = 8; const BALL_SIZE = 4; const BASKET_PLAYER_Y = 15; const BASKET_AI_Y = 85; const BASKET_X = 50; const SPECIAL_THRESHOLD = 100; const SHOT_POWER_RATE = 2; const MAX_SHOT_POWER = 100; // Character stats const characters = { lebron: { name: "LeBron James", specialName: "King's Takeover", shooting: 9, defense: 8, speed: 8, special: "Becomes unstoppable for 10 seconds", image: "https://placehold.co/100x100/9966CC/FFFFFF?text=LeBron", color: "#6A0DAD" // Purple }, kanye: { name: "Kanye West", specialName: "Dropout Beat", shooting: 7, defense: 6, speed: 9, special: "Freezes opponents for 5 seconds", image: "https://placehold.co/100x100/FF9900/FFFFFF?text=Kanye", color: "#FF9900" // Gold }, hitler: { name: "Hitler", specialName: "Blitzkrieg", shooting: 6, defense: 9, speed: 7, special: "Steals the ball and gets a fast break", image: "https://placehold.co/100x100/333333/FFFFFF?text=Hitler", color: "#333333" // Dark gray } }; // Difficulty settings const difficultySettings = { easy: { aiAccuracy: 0.5, aiSpeed: 0.7, aiDefense: 0.6 }, normal: { aiAccuracy: 0.7, aiSpeed: 0.85, aiDefense: 0.75 }, hard: { aiAccuracy: 0.9, aiSpeed: 1, aiDefense: 0.9 } }; // Initialize game useEffect(() => { if (gameState === 'playing') { // Start game loop lastUpdateTimeRef.current = Date.now(); startGameLoop(); // Start game timer const timerInterval = setInterval(() => { setGameTime(time => { if (time <= 0) { clearInterval(timerInterval); setGameState('gameOver'); return 0; } return time - 1; }); // Update shot clock if (possession === 'player') { setShotClock(clock => { if (clock <= 0) { changePossession('ai'); addMessage("Shot clock violation! AI ball"); return 24; } return clock - 1; }); } }, 1000); return () => { cancelAnimationFrame(animationFrameRef.current); clearInterval(timerInterval); }; } }, [gameState]); // Game loop const startGameLoop = () => { const gameLoop = () => { const now = Date.now(); const deltaTime = (now - lastUpdateTimeRef.current) / 1000 * gameSpeed; lastUpdateTimeRef.current = now; updateGame(deltaTime); animationFrameRef.current = requestAnimationFrame(gameLoop); }; animationFrameRef.current = requestAnimationFrame(gameLoop); }; // Update game state const updateGame = (deltaTime) => { // AI movement and decision making if (possession === 'ai') { moveAI(deltaTime); aiDecisionMaking(deltaTime); } else { // AI defense when player has the ball defendAI(deltaTime); } // Teammate AI moveTeammate(deltaTime); // Update ball position if (possession === 'player') { if (isShooting) { updateBallShooting(deltaTime); } else { // Ball follows the player setBallPosition(prev => ({ ...prev, x: playerPosition.x, y: playerPosition.y - 2 })); } } else if (possession === 'ai') { // Ball follows AI setBallPosition(prev => ({ ...prev, x: aiPosition.x, y: aiPosition.y + 2 })); } // Remove old messages setMessages(m => m.filter(msg => Date.now() - msg.time < 3000)); }; // AI movement const moveAI = (deltaTime) => { const settings = difficultySettings[difficulty]; const speed = characters.lebron.speed * settings.aiSpeed * deltaTime * 10; // Move towards the basket when in possession if (possession === 'ai') { const targetX = BASKET_X; const targetY = BASKET_AI_Y - 20; // Position in front of basket const dx = targetX - aiPosition.x; const dy = targetY - aiPosition.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance > 1) { setAiPosition(pos => ({ x: pos.x + (dx / distance) * speed, y: pos.y + (dy / distance) * speed })); } } // Move AI teammate for support const teammateTargetX = aiPosition.x > BASKET_X ? BASKET_X - 15 : BASKET_X + 15; const teammateTargetY = BASKET_AI_Y - 15; const tdx = teammateTargetX - aiTeammatePosition.x; const tdy = teammateTargetY - aiTeammatePosition.y; const tDistance = Math.sqrt(tdx * tdx + tdy * tdy); if (tDistance > 1) { setAiTeammatePosition(pos => ({ x: pos.x + (tdx / tDistance) * speed * 0.8, y: pos.y + (tdy / tDistance) * speed * 0.8 })); } }; // AI defense const defendAI = (deltaTime) => { const settings = difficultySettings[difficulty]; const speed = characters.lebron.speed * settings.aiSpeed * deltaTime * 10; // AI defends the player with the ball const targetX = playerPosition.x; const targetY = playerPosition.y - 10; const dx = targetX - aiPosition.x; const dy = targetY - aiPosition.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5) { setAiPosition(pos => ({ x: pos.x + (dx / distance) * speed, y: pos.y + (dy / distance) * speed })); } // AI teammate defends the player's teammate const teammateTargetX = teammatePosition.x; const teammateTargetY = teammatePosition.y - 5; const tdx = teammateTargetX - aiTeammatePosition.x; const tdy = teammateTargetY - aiTeammatePosition.y; const tDistance = Math.sqrt(tdx * tdx + tdy * tdy); if (tDistance > 5) { setAiTeammatePosition(pos => ({ x: pos.x + (tdx / tDistance) * speed * 0.8, y: pos.y + (tdy / tDistance) * speed * 0.8 })); } // Check for steals if (!isSpecialActive && !isShooting) { const stealChance = settings.aiDefense * 0.01; if (distance < 8 && Math.random() < stealChance) { changePossession('ai'); addMessage("Ball stolen by LeBron!"); setSpecialMeter(m => Math.min(SPECIAL_THRESHOLD, m + 10)); } } }; // AI decision making const aiDecisionMaking = (deltaTime) => { const settings = difficultySettings[difficulty]; // Distance to basket const distanceToBasket = Math.sqrt( Math.pow(aiPosition.x - BASKET_X, 2) + Math.pow(aiPosition.y - BASKET_AI_Y, 2) ); // Shoot if close enough to basket or shot clock running low if (distanceToBasket < 20 || shotClock < 5) { const shootingSkill = characters.lebron.shooting; const shotDifficulty = distanceToBasket / 10; const successChance = (shootingSkill / 10) * settings.aiAccuracy * (1 - shotDifficulty / 10); if (Math.random() < successChance) { // Successful shot setScore(s => ({ ...s, ai: s.ai + 2 })); addMessage("LeBron scores! +2 points for AI"); changePossession('player'); } else { // Missed shot - chance for rebound const reboundChance = 0.5; if (Math.random() < reboundChance) { addMessage("LeBron misses, but AI gets the rebound!"); setShotClock(24); } else { addMessage("LeBron misses! Player gets the rebound"); changePossession('player'); } } } // Pass to teammate occasionally if (Math.random() < 0.01 && distanceToBasket > 15) { // Simulate pass to teammate setAiPosition(aiTeammatePosition); setAiTeammatePosition(aiPosition); addMessage("LeBron passes to teammate!"); } }; // Move teammate AI const moveTeammate = (deltaTime) => { if (!teammate) return; const speed = characters[teammate].speed * deltaTime * 10; if (possession === 'player') { // Position for receiving a pass let targetX, targetY; if (playerPosition.x < BASKET_X) { targetX = BASKET_X + 15; } else { targetX = BASKET_X - 15; } targetY = BASKET_PLAYER_Y + 15; const dx = targetX - teammatePosition.x; const dy = targetY - teammatePosition.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance > 1) { setTeammatePosition(pos => ({ x: pos.x + (dx / distance) * speed, y: pos.y + (dy / distance) * speed })); } } }; // Update ball shooting const updateBallShooting = (deltaTime) => { setBallPosition(pos => { // Calculate trajectory to basket const targetX = BASKET_X; const targetY = BASKET_PLAYER_Y; const startX = playerPosition.x; const startY = playerPosition.y; const dx = targetX - startX; const dy = targetY - startY; const distance = Math.sqrt(dx * dx + dy * dy); // Calculate progress along shot path (0 to 1) const progress = Math.min(1, pos.progress + deltaTime * 2); // Parabolic arc for the shot const x = startX + dx * progress; const y = startY + dy * progress - Math.sin(progress * Math.PI) * 20; // Check if shot is complete if (progress >= 1) { setIsShooting(false); // Calculate shot success based on distance, power, and player skill const shotDifficulty = distance / 10; const powerFactor = Math.abs((shootingPower / MAX_SHOT_POWER) - 0.8); const skillFactor = characters[character].shooting / 10; // Check for defenders nearby const defenderDistance = Math.sqrt( Math.pow(aiPosition.x - playerPosition.x, 2) + Math.pow(aiPosition.y - playerPosition.y, 2) ); const defenseEffect = Math.max(0, 1 - (characters.lebron.defense / 10) * (1 - defenderDistance / 30)); const successChance = skillFactor * (1 - powerFactor) * (1 - shotDifficulty / 10) * defenseEffect; if (Math.random() < successChance) { // Successful shot setScore(s => ({ ...s, player: s.player + 2 })); addMessage(`${characters[character].name} scores! +2 points`); setSpecialMeter(m => Math.min(SPECIAL_THRESHOLD, m + 20)); changePossession('ai'); } else { // Missed shot - chance for rebound const reboundChance = 0.6; if (Math.random() < reboundChance) { addMessage(`${characters[character].name} misses, but gets the rebound!`); setShotClock(24); } else { addMessage(`${characters[character].name} misses! AI gets the rebound`); changePossession('ai'); } } return { x: playerPosition.x, y: playerPosition.y, progress: 0 }; } return { x, y, progress }; }); }; // Handle player movement const handleKeyDown = (e) => { if (gameState !== 'playing' || possession !== 'player') return; const speed = characters[character].speed * 0.5; switch(e.key) { case 'ArrowLeft': setPlayerPosition(p => ({ ...p, x: Math.max(5, p.x - speed) })); break; case 'ArrowRight': setPlayerPosition(p => ({ ...p, x: Math.min(95, p.x + speed) })); break; case 'ArrowUp': setPlayerPosition(p => ({ ...p, y: Math.max(30, p.y - speed) })); break; case 'ArrowDown': setPlayerPosition(p => ({ ...p, y: Math.min(90, p.y + speed) })); break; case ' ': if (!isShooting && possession === 'player') { startShooting(); } break; case 'p': if (possession === 'player') { passBall(); } break; case 'Enter': if (specialMeter >= SPECIAL_THRESHOLD) { activateSpecial(); } break; default: break; } }; // Start shooting process const startShooting = () => { setIsShooting(true); setShootingPower(0); // Power meter increases const powerInterval = setInterval(() => { setShootingPower(power => { if (power >= MAX_SHOT_POWER) { clearInterval(powerInterval); return MAX_SHOT_POWER; } return power + SHOT_POWER_RATE; }); }, 20); // Auto-release after max power setTimeout(() => { clearInterval(powerInterval); if (isShooting) { releaseShotWithCurrentPower(); } }, MAX_SHOT_POWER / SHOT_POWER_RATE * 20 + 100); }; // Release shot with current power const releaseShotWithCurrentPower = () => { setBallPosition(pos => ({ ...pos, progress: 0 })); }; // Pass ball to teammate const passBall = () => { if (possession !== 'player' || isShooting) return; // Swap positions const tempPos = playerPosition; setPlayerPosition(teammatePosition); setTeammatePosition(tempPos); addMessage(`${characters[character].name} passes to ${characters[teammate].name}!`); }; // Change possession const changePossession = (newPossession) => { setPossession(newPossession); setShotClock(24); if (newPossession === 'player') { // Reset player and ball positions for inbound setPlayerPosition({ x: 50, y: 70 }); setTeammatePosition({ x: 30, y: 70 }); setBallPosition({ x: 50, y: 70, progress: 0 }); } else { // Reset AI positions for inbound setAiPosition({ x: 50, y: 30 }); setAiTeammatePosition({ x: 70, y: 30 }); setBallPosition({ x: 50, y: 30, progress: 0 }); } }; // Add message to the message list const addMessage = (text) => { setMessages(prev => [...prev, { text, time: Date.now() }]); }; // Activate special ability const activateSpecial = () => { setIsSpecialActive(true); setSpecialMeter(0); if (character === 'kanye') { // Kanye's special: freeze opponents const originalAiPos = { ...aiPosition }; const originalAiTeammatePos = { ...aiTeammatePosition }; addMessage(`${characters[character].specialName} activated! Opponents frozen!`); // Freeze AI movement const unfreezeTime = setTimeout(() => { setIsSpecialActive(false); addMessage("Opponents unfrozen!"); }, 5000); return () => clearTimeout(unfreezeTime); } else if (character === 'hitler') { // Hitler's special: steal ball and fast break changePossession('player'); setPlayerPosition({ x: BASKET_X, y: BASKET_PLAYER_Y + 15 }); addMessage(`${characters[character].specialName} activated! Ball stolen!`); setTimeout(() => { setIsSpecialActive(false); }, 2000); } // Reset special state after animation setTimeout(() => { setIsSpecialActive(false); }, 2000); }; // Start the game const startGame = (selectedCharacter) => { setCharacter(selectedCharacter); // Set teammate as the non-selected character const availableTeammates = Object.keys(characters).filter(c => c !== selectedCharacter && c !== 'lebron'); setTeammate(availableTeammates[0]); setGameState('playing'); setScore({ player: 0, ai: 0 }); setGameTime(60); setShotClock(24); setPossession('player'); setPlayerPosition({ x: 70, y: 70 }); setTeammatePosition({ x: 30, y: 70 }); setAiPosition({ x: 50, y: 30 }); setAiTeammatePosition({ x: 70, y: 30 }); setBallPosition({ x: 70, y: 70, progress: 0 }); setMessages([]); setSpecialMeter(0); // Focus on game area for keyboard controls if (gameAreaRef.current) { gameAreaRef.current.focus(); } addMessage(`Game started with ${characters[selectedCharacter].name}!`); addMessage(`Your teammate is ${characters[availableTeammates[0]].name}`); }; // Restart the game const restartGame = () => { setGameState('start'); }; // Handle touch/mouse movement for mobile const handlePointerMove = (e) => { if (gameState !== 'playing' || possession !== 'player') return; const rect = e.currentTarget.getBoundingClientRect(); const x = ((e.clientX - rect.left) / rect.width) * 100; const y = ((e.clientY - rect.top) / rect.height) * 100; setPlayerPosition({ x: Math.min(95, Math.max(5, x)), y: Math.min(90, Math.max(30, y)) }); }; // Handle shooting on click/tap const handlePointerDown = () => { if (gameState === 'playing' && possession === 'player' && !isShooting) { startShooting(); } }; // Handle shooting release on pointer up const handlePointerUp = () => { if (gameState === 'playing' && possession === 'player' && isShooting) { releaseShotWithCurrentPower(); } }; // Format time as MM:SS const formatTime = (seconds) => { const mins = Math.floor(seconds / 60); const secs = seconds % 60; return `${mins}:${secs < 10 ? '0' : ''}${secs}`; }; return (
Use arrow keys to move, SPACE to shoot, P to pass, ENTER for special move
Or use touch/mouse controls on mobile devices
Use arrow keys to move, SPACE to shoot, ENTER for special move
Or use touch/mouse controls on mobile devices
Final Score: {score}
You reached Level {level}