diff --git a/app/luca/Luca.tsx b/app/luca/Luca.tsx index 3c5c8a9..170e930 100644 --- a/app/luca/Luca.tsx +++ b/app/luca/Luca.tsx @@ -1,25 +1,118 @@ // Luca.tsx "use client"; -import React, { useState } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import './Luca.css'; // Import specific styles for Luca +const WIDTH = 20; +const HEIGHT = 20; +const CELL_SIZE = 20; + const Luca = () => { // State to keep track of the number of clicks const [clickCount, setClickCount] = useState(0); - // Function to handle button click - const handleClick = () => { - setClickCount(clickCount + 1); + // State and logic for the Snake game + const [snake, setSnake] = useState([{ x: 5, y: 5 }]); + const [food, setFood] = useState({ x: 10, y: 10 }); + const [direction, setDirection] = useState('RIGHT'); + const [score, setScore] = useState(0); + const [gameOver, setGameOver] = useState(false); + + const moveSnake = useCallback(() => { + if (gameOver) return; + + let newSnake = [...snake]; + let head = { ...newSnake[0] }; + + // Update head position based on direction + switch (direction) { + case 'UP': + head.y -= 1; + break; + case 'DOWN': + head.y += 1; + break; + case 'LEFT': + head.x -= 1; + break; + case 'RIGHT': + head.x += 1; + break; + } + + // Check if the new head position is the food + const hasEatenFood = head.x === food.x && head.y === food.y; + + // Update the snake's body + newSnake = [head, ...newSnake]; + + if (hasEatenFood) { + // Generate new food position + setFood({ + x: Math.floor(Math.random() * WIDTH), + y: Math.floor(Math.random() * HEIGHT), + }); + setScore(score + 1); // Increase the score + } else { + // Remove the tail segment if not eating food + newSnake.pop(); + } + + // Check for collisions + if ( + head.x < 0 || + head.x >= WIDTH || + head.y < 0 || + head.y >= HEIGHT || + newSnake.slice(1).some(seg => seg.x === head.x && seg.y === head.y) + ) { + setGameOver(true); + return; + } + + setSnake(newSnake); + }, [direction, snake, food, gameOver, score]); + + useEffect(() => { + const interval = setInterval(moveSnake, 200); + return () => clearInterval(interval); + }, [moveSnake]); + + const handleKeyDown = (e: KeyboardEvent) => { + // Prevent default behavior for 'W', 'A', 'S', 'D' to avoid scrolling + if (['KeyW', 'KeyA', 'KeyS', 'KeyD'].includes(e.code)) { + e.preventDefault(); + } + + switch (e.code) { + case 'KeyW': + if (direction !== 'DOWN') setDirection('UP'); + break; + case 'KeyS': + if (direction !== 'UP') setDirection('DOWN'); + break; + case 'KeyA': + if (direction !== 'RIGHT') setDirection('LEFT'); + break; + case 'KeyD': + if (direction !== 'LEFT') setDirection('RIGHT'); + break; + } }; + useEffect(() => { + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [direction]); + return (
Welcome, Luca! This is your programming space.
{/* Button to count clicks */} -Score: {score}
+