import React, { useState, useRef, useEffect } from 'react'; import GameCanvas from './components/GameCanvas'; import { GameStatus, MiaCustomization } from './types'; import { Play, RotateCcw, Trophy, Heart, ArrowRight, Sparkles, Palette, Pause, Home } from 'lucide-react'; import { MAX_LIVES, FUR_COLORS, COLLAR_COLORS } from './constants'; const App: React.FC = () => { const [gameStatus, setGameStatus] = useState(GameStatus.START_SCREEN); const [score, setScore] = useState(0); const [lives, setLives] = useState(MAX_LIVES); const [highScore, setHighScore] = useState(0); const [showDamageOverlay, setShowDamageOverlay] = useState(false); const [customizationTab, setCustomizationTab] = useState<'body' | 'head' | 'style'>('body'); const [customization, setCustomization] = useState({ furColor: FUR_COLORS.RUSTY, collarColor: COLLAR_COLORS.RED, hat: 'none', glasses: 'none', shirt: 'none' }); const prevLivesRef = useRef(MAX_LIVES); const canvasRef = useRef(null); // Trigger damage overlay when lives decrease useEffect(() => { if (lives < prevLivesRef.current) { setShowDamageOverlay(true); const t = setTimeout(() => setShowDamageOverlay(false), 300); return () => clearTimeout(t); } prevLivesRef.current = lives; }, [lives]); const handleStart = () => { setGameStatus(GameStatus.PLAYING); setLives(MAX_LIVES); prevLivesRef.current = MAX_LIVES; }; const handleRestart = () => { if (score > highScore) { setHighScore(score); } // Fully reset logic setGameStatus(GameStatus.START_SCREEN); setScore(0); setLives(MAX_LIVES); prevLivesRef.current = MAX_LIVES; }; const handleNextLevel = () => { setGameStatus(GameStatus.PLAYING); }; const updateStatus = (status: GameStatus) => { if (status === GameStatus.GAME_OVER) { if (score > highScore) setHighScore(score); } setGameStatus(status); }; return (
{/* Game Layer */}
{/* Damage Overlay */}
{/* UI Layer - HUD */} {(gameStatus === GameStatus.PLAYING || gameStatus === GameStatus.LEVEL_COMPLETE || gameStatus === GameStatus.PAUSED) && (
{/* Score */}
Score {score.toString().padStart(5, '0')}
{/* Lives */}
{Array.from({length: MAX_LIVES}).map((_, i) => ( ))}
{/* Best Score */}
Best {highScore.toString().padStart(5, '0')}
{/* Pause Button */}
)} {/* UI Layer - Pause Menu */} {gameStatus === GameStatus.PAUSED && (

PAUSED

)} {/* UI Layer - Start Screen */} {gameStatus === GameStatus.START_SCREEN && (
🐶

Mia's Clean Run

Clean the house and avoid the cats!

)} {/* UI Layer - Customization Screen */} {gameStatus === GameStatus.CUSTOMIZE && (

Style Your Pup!

{/* Tabs */}
{customizationTab === 'body' && ( <>

Fur Color

{Object.entries(FUR_COLORS).map(([name, color]) => (

Collar Color

{Object.entries(COLLAR_COLORS).map(([name, color]) => (
)} {customizationTab === 'head' && ( <>

Hats

{[ {id: 'none', label: 'None', icon: '🚫'}, {id: 'party', label: 'Party', icon: '🎉'}, {id: 'tophat', label: 'Fancy', icon: '🎩'}, {id: 'bow', label: 'Bow', icon: '🎀'}, {id: 'cowboy', label: 'Cowboy', icon: '🤠'}, {id: 'crown', label: 'Royal', icon: '👑'}, ].map((item) => ( ))}

Glasses

{[ {id: 'none', label: 'None', icon: '🚫'}, {id: 'sunglasses', label: 'Cool', icon: '😎'}, {id: 'nerd', label: 'Smart', icon: '🤓'}, {id: '3d', label: 'Movie', icon: '🍿'}, ].map((item) => ( ))}
)} {customizationTab === 'style' && (

Outfits

{[ {id: 'none', label: 'Au Naturel', icon: '🐕'}, {id: 'bandana', label: 'Bandana', icon: '🧣'}, {id: 'vest', label: 'Service Vest', icon: '🦺'}, {id: 'superhero', label: 'Hero Cape', icon: '🦸'}, ].map((item) => ( ))}
)}
)} {/* UI Layer - Level Complete */} {gameStatus === GameStatus.LEVEL_COMPLETE && (

Level Complete!

Mia is a good girl!

Current Score
{score}
)} {/* UI Layer - Game Over */} {gameStatus === GameStatus.GAME_OVER && (

Oops!

Mia ran out of lives!

Final Score
{score}
)}
); }; export default App;