main #4

Merged
Patrick_Pluto merged 3 commits from React-Group/react-typescript-test:main into main 2024-09-05 13:48:33 +02:00
Showing only changes of commit 28e6fe9d9e - Show all commits

View file

@ -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 (
<div className="programmer-space luca">
<h2>Luca's Space</h2>
<p>Welcome, Luca! This is your programming space.</p>
{/* Button to count clicks */}
<button onClick={handleClick} className="click-button">
<button onClick={() => setClickCount(clickCount + 1)} className="click-button">
Click me
</button>
<p>You've clicked the button {clickCount} times!</p>
@ -30,6 +123,63 @@ const Luca = () => {
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
</div>
{/* Snake game */}
<div
className="snake-game"
style={{
position: 'relative',
width: WIDTH * CELL_SIZE,
height: HEIGHT * CELL_SIZE,
border: '1px solid black',
marginTop: '20px',
}}
>
{snake.map((segment, index) => (
<div
key={index}
style={{
position: 'absolute',
left: segment.x * CELL_SIZE,
top: segment.y * CELL_SIZE,
width: CELL_SIZE,
height: CELL_SIZE,
backgroundColor: 'green',
}}
/>
))}
<div
style={{
position: 'absolute',
left: food.x * CELL_SIZE,
top: food.y * CELL_SIZE,
width: CELL_SIZE,
height: CELL_SIZE,
backgroundColor: 'red',
}}
/>
{gameOver && (
<div
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
backgroundColor: 'rgba(0,0,0,0.5)',
color: 'white',
padding: '10px',
borderRadius: '5px',
}}
>
Game Over
</div>
)}
</div>
{/* Score display */}
<div className="score" style={{ marginTop: '20px', fontSize: '18px' }}>
<p>Score: {score}</p>
</div>
</div>
);
};