diff --git a/src/App.css b/src/App.css index 53aa32e..b2defa1 100644 --- a/src/App.css +++ b/src/App.css @@ -5,4 +5,21 @@ justify-content: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; + box-sizing: border-box; + width: 100%; +} + +@media (max-width: 768px) { + .app { + padding: 15px; + align-items: flex-start; + padding-top: 20px; + } +} + +@media (max-width: 480px) { + .app { + padding: 10px; + padding-top: 15px; + } } diff --git a/src/FlappyBird.css b/src/FlappyBird.css index 1f763a5..9e4b7b5 100644 --- a/src/FlappyBird.css +++ b/src/FlappyBird.css @@ -4,6 +4,11 @@ padding: 20px; text-align: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; + width: 100%; + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; } .flappy-bird-container h1 { @@ -15,19 +20,25 @@ .game-area { position: relative; - display: inline-block; - margin-bottom: 20px; + display: block; + margin: 0 auto 20px auto; border-radius: 10px; box-shadow: 0 8px 32px rgba(0,0,0,0.2); overflow: hidden; + width: 100%; + max-width: 800px; } .game-canvas { display: block; + margin: 0 auto; border: 3px solid #34495e; border-radius: 10px; cursor: pointer; background: linear-gradient(to bottom, #87CEEB 0%, #98FB98 100%); + width: 100%; + height: auto; + aspect-ratio: 2 / 1; } .game-canvas:hover { @@ -106,17 +117,24 @@ /* Responsive design */ @media (max-width: 850px) { .flappy-bird-container { - padding: 10px; + padding: 15px; + max-width: 100%; + } + + .game-area { + width: 100%; + margin-bottom: 15px; } .game-canvas { width: 100%; - max-width: 800px; - height: auto; + max-width: 100%; + border-width: 2px; } .flappy-bird-container h1 { font-size: 2rem; + margin-bottom: 15px; } .scores { @@ -124,7 +142,7 @@ } .game-message { - max-width: 250px; + max-width: 280px; padding: 15px 20px; } @@ -135,11 +153,28 @@ .game-message.game-over p:first-child { font-size: 20px; } + + .instructions { + margin-top: 15px; + } } @media (max-width: 480px) { + .flappy-bird-container { + padding: 10px; + } + .flappy-bird-container h1 { font-size: 1.5rem; + margin-bottom: 10px; + } + + .game-area { + margin-bottom: 10px; + } + + .game-canvas { + border-width: 2px; } .scores { @@ -148,11 +183,50 @@ font-size: 12px; } + .game-message { + max-width: 240px; + padding: 12px 15px; + } + + .game-message p { + font-size: 13px; + margin: 6px 0; + } + + .game-message.game-over p:first-child { + font-size: 18px; + } + .instructions { - padding: 15px; + padding: 12px; + margin-top: 10px; } .instructions p { - font-size: 14px; + font-size: 13px; + margin: 8px 0; + } +} + +@media (max-width: 320px) { + .flappy-bird-container { + padding: 8px; + } + + .flappy-bird-container h1 { + font-size: 1.3rem; + } + + .game-message { + max-width: 200px; + padding: 10px 12px; + } + + .instructions { + padding: 10px; + } + + .instructions p { + font-size: 12px; } } \ No newline at end of file diff --git a/src/FlappyBird.jsx b/src/FlappyBird.jsx index f36bd33..2fc7a7e 100644 --- a/src/FlappyBird.jsx +++ b/src/FlappyBird.jsx @@ -39,6 +39,26 @@ function FlappyBird() { frameCount: 0 }) + // Update canvas size to maintain aspect ratio + const updateCanvasSize = useCallback(() => { + const canvas = canvasRef.current + if (!canvas) return + + const container = canvas.parentElement + const containerWidth = container.clientWidth + const aspectRatio = GAME_CONFIG.CANVAS_WIDTH / GAME_CONFIG.CANVAS_HEIGHT + + let canvasWidth = Math.min(containerWidth - 20, GAME_CONFIG.CANVAS_WIDTH) + let canvasHeight = canvasWidth / aspectRatio + + canvas.style.width = `${canvasWidth}px` + canvas.style.height = `${canvasHeight}px` + + // Set internal resolution + canvas.width = GAME_CONFIG.CANVAS_WIDTH + canvas.height = GAME_CONFIG.CANVAS_HEIGHT + }, []) + const jump = useCallback(() => { if (gameState === GAME_STATES.START) { setGameState(GAME_STATES.PLAYING) @@ -167,6 +187,17 @@ function FlappyBird() { gameLoopRef.current = requestAnimationFrame(gameLoop) }, [gameState, score, highScore, checkCollision]) + useEffect(() => { + updateCanvasSize() + + const handleResize = () => { + updateCanvasSize() + } + + window.addEventListener('resize', handleResize) + return () => window.removeEventListener('resize', handleResize) + }, [updateCanvasSize]) + useEffect(() => { gameLoopRef.current = requestAnimationFrame(gameLoop) return () => {