GameScreen feltöltés

This commit is contained in:
2025-08-23 00:15:27 +02:00
parent 34a6df5949
commit d8598755e0
5 changed files with 434 additions and 17 deletions
@@ -0,0 +1,24 @@
// Scaling factor for vertical offsets
const offsetScalingFactor = 0.4;
// Predefined vertical offsets represented as a 5x20 grid of zeros
export const verticalOffsets = [
0,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
];
/**
* Gets a vertical offset value from the predefined array
* @param {number} index - Index to retrieve from the offsets array
* @returns {number} Offset value
*/
export const getVerticalOffset = (index) => {
const normalizedIndex = index % verticalOffsets.length;
const offset = verticalOffsets[normalizedIndex >= 0 ? normalizedIndex : 0];
return offset * offsetScalingFactor; // Apply scaling factor
};
@@ -0,0 +1,139 @@
import React, { useState, useEffect, useRef } from 'react';
const Dice = ({ onRoll }) => {
const [diceValue, setDiceValue] = useState(1);
const [isRolling, setIsRolling] = useState(false);
const animationRef = useRef(null);
const rollTimeoutRef = useRef(null);
const diceFaces = [
[<div key="center" className="dice-dot"></div>],
[<div key="top-left" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>],
[<div key="top-left" className="dice-dot"></div>, <div key="center" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>],
[<div key="top-left" className="dice-dot"></div>, <div key="top-right" className="dice-dot"></div>,
<div key="bottom-left" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>],
[<div key="top-left" className="dice-dot"></div>, <div key="top-right" className="dice-dot"></div>,
<div key="center" className="dice-dot"></div>,
<div key="bottom-left" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>],
[<div key="top-left" className="dice-dot"></div>, <div key="top-right" className="dice-dot"></div>,
<div key="middle-left" className="dice-dot"></div>, <div key="middle-right" className="dice-dot"></div>,
<div key="bottom-left" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>]
];
useEffect(() => {
return () => {
if (animationRef.current) cancelAnimationFrame(animationRef.current);
if (rollTimeoutRef.current) clearTimeout(rollTimeoutRef.current);
};
}, []);
const rollDice = () => {
if (isRolling) return;
setIsRolling(true);
let duration = 0;
const rollInterval = 80; // ms between dice face changes
const maxDuration = 1500; // total animation time
const rollAnimation = () => {
const randomValue = Math.floor(Math.random() * 6) + 1;
setDiceValue(randomValue);
duration += rollInterval;
if (duration < maxDuration) {
// Speed effect: slow down towards the end
const nextInterval = rollInterval * (1 + (duration / maxDuration) * 2);
rollTimeoutRef.current = setTimeout(() => {
animationRef.current = requestAnimationFrame(rollAnimation);
}, nextInterval);
} else {
// Final roll
const finalValue = Math.floor(Math.random() * 6) + 1;
setDiceValue(finalValue);
setIsRolling(false);
if (onRoll) onRoll(finalValue);
}
};
animationRef.current = requestAnimationFrame(rollAnimation);
};
return (
<div
className={`dice-container ${isRolling ? 'rolling' : ''}`}
onClick={rollDice}
>
<div className="dice">
{diceFaces[diceValue - 1]}
</div>
<style jsx>{`
.dice-container {
width: 80px;
height: 80px;
perspective: 600px;
cursor: pointer;
margin: 0 auto;
transition: transform 0.2s;
}
.dice-container:hover {
transform: scale(1.05);
}
.dice-container:active {
transform: scale(0.95);
}
.dice {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.2s;
display: flex;
align-items: center;
justify-content: center;
background-color: #e63946;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
padding: 8px;
}
.rolling .dice {
animation: roll 0.5s infinite linear;
}
@keyframes roll {
0% { transform: rotateX(0deg) rotateY(0deg); }
25% { transform: rotateX(90deg) rotateY(45deg); }
50% { transform: rotateX(180deg) rotateY(90deg); }
75% { transform: rotateX(270deg) rotateY(135deg); }
100% { transform: rotateX(360deg) rotateY(180deg); }
}
.dice-dot {
width: 14px;
height: 14px;
border-radius: 50%;
background-color: white;
position: absolute;
box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
}
/* Positioning dots */
.dice-dot:nth-child(1) { top: 50%; left: 50%; transform: translate(-50%, -50%); } /* Center */
.dice-dot:nth-child(2) { top: 20%; left: 20%; } /* Top-left */
.dice-dot:nth-child(3) { bottom: 20%; right: 20%; } /* Bottom-right */
.dice-dot:nth-child(4) { top: 20%; right: 20%; } /* Top-right */
.dice-dot:nth-child(5) { bottom: 20%; left: 20%; } /* Bottom-left */
.dice-dot:nth-child(6) { top: 50%; left: 20%; transform: translateY(-50%); } /* Middle-left */
.dice-dot:nth-child(7) { top: 50%; right: 20%; transform: translateY(-50%); } /* Middle-right */
`}</style>
</div>
);
};
export default Dice;
@@ -0,0 +1,20 @@
// Predefined vertical offsets represented as a 5x20 grid of zeros
export const verticalOffsets = [
0,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
-35, -10, -5, 10, 15, 12, 5, -5, -12, -15, -12, -5, 5, 12, 15, 12, 5, -5, 10, 35,
];
/**
* Gets a vertical offset value from the predefined array
* @param {number} index - Index to retrieve from the offsets array
* @returns {number} Offset value
*/
export const getVerticalOffset = (index) => {
const normalizedIndex = index % verticalOffsets.length;
return verticalOffsets[normalizedIndex >= 0 ? normalizedIndex : 0];
};