dobokocka mukodik :O #56
@@ -66,12 +66,17 @@ const GameScreen = () => {
|
|||||||
{ id: 3, name: "Fürtös", position: 68, score: 14, color: "bg-yellow-600", emoji: "😂" },
|
{ id: 3, name: "Fürtös", position: 68, score: 14, color: "bg-yellow-600", emoji: "😂" },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// New: selected dice value from dropdown (null = none)
|
||||||
|
const [selectedDice, setSelectedDice] = useState(null)
|
||||||
|
|
||||||
// Sort players by position in descending order
|
// Sort players by position in descending order
|
||||||
const sortedPlayers = [...players].sort((a, b) => b.position - a.position)
|
const sortedPlayers = [...players].sort((a, b) => b.position - a.position)
|
||||||
|
|
||||||
// Handle dice roll
|
// Handle dice roll completion
|
||||||
const handleDiceRoll = (value) => {
|
const handleDiceRoll = (value) => {
|
||||||
console.log("Rolled:", value)
|
console.log("Rolled:", value)
|
||||||
|
// reset dropdown selection after roll
|
||||||
|
setSelectedDice(null)
|
||||||
// You can add logic here to move the current player based on the dice value
|
// You can add logic here to move the current player based on the dice value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,9 +123,6 @@ const GameScreen = () => {
|
|||||||
{/* Háttér */}
|
{/* Háttér */}
|
||||||
<div className="absolute w-full h-full opacity-10 pointer-events-none overflow-hidden">
|
<div className="absolute w-full h-full opacity-10 pointer-events-none overflow-hidden">
|
||||||
{[...Array(35)].map((_, i) => (
|
{[...Array(35)].map((_, i) => (
|
||||||
// Sajat pulse effect! => node_modules/tailwindcss/index.css:
|
|
||||||
// --animate-pulse8: pulse 6s cubic-bezier(0.4, 0.2, 0.6, 1) infinite;
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
className="absolute rounded-full bg-teal-600 animate-pulse8"
|
className="absolute rounded-full bg-teal-600 animate-pulse8"
|
||||||
@@ -222,8 +224,31 @@ const GameScreen = () => {
|
|||||||
{/* Dice Container */}
|
{/* Dice Container */}
|
||||||
<div className="bg-gray-800 rounded-xl p-4 shadow-lg border border-teal-700 text-center">
|
<div className="bg-gray-800 rounded-xl p-4 shadow-lg border border-teal-700 text-center">
|
||||||
<h2 className="text-xl font-semibold mb-3 text-teal-300">Dobókocka</h2>
|
<h2 className="text-xl font-semibold mb-3 text-teal-300">Dobókocka</h2>
|
||||||
<p className="text-gray-300 text-sm mb-4">Kattints a kockára dobáshoz!</p>
|
<p className="text-gray-300 text-sm mb-4">
|
||||||
<Dice onRoll={handleDiceRoll} />
|
Kattints a kockára dobáshoz vagy válassz egy számot az alábbiból!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Dropdown to select number 1-6 (triggers animated roll to that number) */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<select
|
||||||
|
value={selectedDice ?? ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
const v = e.target.value ? Number(e.target.value) : null
|
||||||
|
setSelectedDice(v)
|
||||||
|
}}
|
||||||
|
className="bg-gray-900 text-gray-200 rounded-md p-2 border border-gray-700"
|
||||||
|
>
|
||||||
|
<option value="">Válassz számot...</option>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2">2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
<option value="4">4</option>
|
||||||
|
<option value="5">5</option>
|
||||||
|
<option value="6">6</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dice onRoll={handleDiceRoll} selectedValue={selectedDice} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,74 +1,103 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from "react"
|
||||||
|
import { dotPositions } from "./diceDotPositions"
|
||||||
|
|
||||||
const Dice = ({ onRoll }) => {
|
const Dice = ({ onRoll, selectedValue }) => {
|
||||||
const [diceValue, setDiceValue] = useState(1);
|
const [diceValue, setDiceValue] = useState(1)
|
||||||
const [isRolling, setIsRolling] = useState(false);
|
const [isRolling, setIsRolling] = useState(false)
|
||||||
const animationRef = useRef(null);
|
const animationRef = useRef(null)
|
||||||
const rollTimeoutRef = useRef(null);
|
const rollTimeoutRef = useRef(null)
|
||||||
|
|
||||||
const diceFaces = [
|
const diceFaces = [
|
||||||
[<div key="center" className="dice-dot"></div>],
|
[<div key="center" className="dice-dot" style={dotPositions.center}></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" style={dotPositions.topLeft}></div>,
|
||||||
[<div key="top-left" className="dice-dot"></div>, <div key="top-right" className="dice-dot"></div>,
|
<div key="bottom-right" className="dice-dot" style={dotPositions.bottomRight}></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="top-left" className="dice-dot" style={dotPositions.topLeft}></div>,
|
||||||
<div key="bottom-left" className="dice-dot"></div>, <div key="bottom-right" className="dice-dot"></div>],
|
<div key="center" className="dice-dot" style={dotPositions.center}></div>,
|
||||||
[<div key="top-left" className="dice-dot"></div>, <div key="top-right" className="dice-dot"></div>,
|
<div key="bottom-right" className="dice-dot" style={dotPositions.bottomRight}></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>]
|
[
|
||||||
];
|
<div key="top-left" className="dice-dot" style={dotPositions.topLeft}></div>,
|
||||||
|
<div key="top-right" className="dice-dot" style={dotPositions.topRight}></div>,
|
||||||
|
<div key="bottom-left" className="dice-dot" style={dotPositions.bottomLeft}></div>,
|
||||||
|
<div key="bottom-right" className="dice-dot" style={dotPositions.bottomRight}></div>,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
<div key="top-left" className="dice-dot" style={dotPositions.topLeft}></div>,
|
||||||
|
<div key="top-right" className="dice-dot" style={dotPositions.topRight}></div>,
|
||||||
|
<div key="center" className="dice-dot" style={dotPositions.center}></div>,
|
||||||
|
<div key="bottom-left" className="dice-dot" style={dotPositions.bottomLeft}></div>,
|
||||||
|
<div key="bottom-right" className="dice-dot" style={dotPositions.bottomRight}></div>,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
<div key="top-left" className="dice-dot" style={dotPositions.topLeft}></div>,
|
||||||
|
<div key="top-right" className="dice-dot" style={dotPositions.topRight}></div>,
|
||||||
|
<div key="middle-left" className="dice-dot" style={dotPositions.middleLeft}></div>,
|
||||||
|
<div key="middle-right" className="dice-dot" style={dotPositions.middleRight}></div>,
|
||||||
|
<div key="bottom-left" className="dice-dot" style={dotPositions.bottomLeft}></div>,
|
||||||
|
<div key="bottom-right" className="dice-dot" style={dotPositions.bottomRight}></div>,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
if (animationRef.current) cancelAnimationFrame(animationRef.current);
|
if (animationRef.current) cancelAnimationFrame(animationRef.current)
|
||||||
if (rollTimeoutRef.current) clearTimeout(rollTimeoutRef.current);
|
if (rollTimeoutRef.current) clearTimeout(rollTimeoutRef.current)
|
||||||
};
|
}
|
||||||
}, []);
|
}, [])
|
||||||
|
|
||||||
const rollDice = () => {
|
// Helper that starts the rolling animation and finishes with targetValue if provided
|
||||||
if (isRolling) return;
|
const startRoll = (targetValue = null) => {
|
||||||
|
if (isRolling) return
|
||||||
|
|
||||||
setIsRolling(true);
|
setIsRolling(true)
|
||||||
|
|
||||||
let duration = 0;
|
let duration = 0
|
||||||
const rollInterval = 80; // ms between dice face changes
|
const rollInterval = 80 // ms between dice face changes
|
||||||
const maxDuration = 1500; // total animation time
|
const maxDuration = 1500 // total animation time
|
||||||
|
|
||||||
const rollAnimation = () => {
|
const rollAnimation = () => {
|
||||||
const randomValue = Math.floor(Math.random() * 6) + 1;
|
const randomValue = Math.floor(Math.random() * 6) + 1
|
||||||
setDiceValue(randomValue);
|
setDiceValue(randomValue)
|
||||||
|
|
||||||
duration += rollInterval;
|
duration += rollInterval
|
||||||
|
|
||||||
if (duration < maxDuration) {
|
if (duration < maxDuration) {
|
||||||
// Speed effect: slow down towards the end
|
// Speed effect: slow down towards the end
|
||||||
const nextInterval = rollInterval * (1 + (duration / maxDuration) * 2);
|
const nextInterval = rollInterval * (1 + (duration / maxDuration) * 2)
|
||||||
rollTimeoutRef.current = setTimeout(() => {
|
rollTimeoutRef.current = setTimeout(() => {
|
||||||
animationRef.current = requestAnimationFrame(rollAnimation);
|
animationRef.current = requestAnimationFrame(rollAnimation)
|
||||||
}, nextInterval);
|
}, nextInterval)
|
||||||
} else {
|
} else {
|
||||||
// Final roll
|
// Final roll (use targetValue if provided)
|
||||||
const finalValue = Math.floor(Math.random() * 6) + 1;
|
const finalValue = targetValue != null ? Number(targetValue) : Math.floor(Math.random() * 6) + 1
|
||||||
setDiceValue(finalValue);
|
setDiceValue(finalValue)
|
||||||
setIsRolling(false);
|
setIsRolling(false)
|
||||||
|
|
||||||
if (onRoll) onRoll(finalValue);
|
if (onRoll) onRoll(finalValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
animationRef.current = requestAnimationFrame(rollAnimation);
|
animationRef.current = requestAnimationFrame(rollAnimation)
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Click to roll randomly
|
||||||
|
const rollDice = () => {
|
||||||
|
startRoll(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parent provides a selectedValue, animate to that value
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedValue != null) {
|
||||||
|
startRoll(Number(selectedValue))
|
||||||
|
}
|
||||||
|
}, [selectedValue])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={`dice-container ${isRolling ? "rolling" : ""}`} onClick={rollDice}>
|
||||||
className={`dice-container ${isRolling ? 'rolling' : ''}`}
|
<div className="dice">{diceFaces[diceValue - 1]}</div>
|
||||||
onClick={rollDice}
|
|
||||||
>
|
|
||||||
<div className="dice">
|
|
||||||
{diceFaces[diceValue - 1]}
|
|
||||||
</div>
|
|
||||||
<style jsx>{`
|
<style jsx>{`
|
||||||
.dice-container {
|
.dice-container {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
@@ -98,7 +127,7 @@ const Dice = ({ onRoll }) => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #e63946;
|
background-color: #e63946;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.3);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,11 +136,21 @@ const Dice = ({ onRoll }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes roll {
|
@keyframes roll {
|
||||||
0% { transform: rotateX(0deg) rotateY(0deg); }
|
0% {
|
||||||
25% { transform: rotateX(90deg) rotateY(45deg); }
|
transform: rotateX(0deg) rotateY(0deg);
|
||||||
50% { transform: rotateX(180deg) rotateY(90deg); }
|
}
|
||||||
75% { transform: rotateX(270deg) rotateY(135deg); }
|
25% {
|
||||||
100% { transform: rotateX(360deg) rotateY(180deg); }
|
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 {
|
.dice-dot {
|
||||||
@@ -120,20 +159,13 @@ const Dice = ({ onRoll }) => {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
|
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Positioning dots */
|
/* removed :nth-child positioning — positions are provided inline from diceDotPositions.js */
|
||||||
.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>
|
`}</style>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default Dice;
|
export default Dice
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export const dotPositions = {
|
||||||
|
center: { top: "50%", left: "50%", transform: "translate(-50%, -50%)" },
|
||||||
|
topLeft: { top: "20%", left: "20%" },
|
||||||
|
bottomRight: { bottom: "20%", right: "20%" },
|
||||||
|
topRight: { top: "20%", right: "20%" },
|
||||||
|
bottomLeft: { bottom: "20%", left: "20%" },
|
||||||
|
middleLeft: { top: "50%", left: "20%", transform: "translateY(-50%)" },
|
||||||
|
middleRight: { top: "50%", right: "20%", transform: "translateY(-50%)" },
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user