Improve dice rolls.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { CSSProperties } from 'react'
|
||||
|
||||
// How long the dice scramble before settling, and how fast the faces flicker
|
||||
// while they do. ROLL_MS is shared with BattlePhase so damage lands exactly
|
||||
// when the dice settle.
|
||||
export const ROLL_MS = 650
|
||||
const TICK_MS = 70
|
||||
|
||||
// DiceRoll shows one rock die per rolled face in fixed slots under the
|
||||
// thrower's side: they shake and flicker through faces in place, then settle
|
||||
// on the values the server actually rolled. Faces carry rock icons (0, 1, or
|
||||
// 2 rocks) — the same die the game uses, not a pip D6. Mount it with a `key`
|
||||
// that changes per rock event so the scramble replays every time.
|
||||
export function DiceRoll({ dice, side }: { dice: number[]; side: 'left' | 'right' }) {
|
||||
const [display, setDisplay] = useState<number[]>(dice)
|
||||
const [settled, setSettled] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const flicker = window.setInterval(() => {
|
||||
setDisplay(dice.map(() => Math.floor(Math.random() * 3)))
|
||||
}, TICK_MS)
|
||||
const stop = window.setTimeout(() => {
|
||||
window.clearInterval(flicker)
|
||||
setDisplay(dice)
|
||||
setSettled(true)
|
||||
}, ROLL_MS)
|
||||
return () => {
|
||||
window.clearInterval(flicker)
|
||||
window.clearTimeout(stop)
|
||||
}
|
||||
// Runs once per mount; the caller remounts (via key) for each new roll.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={`dice-roll dice-roll-${side}`} aria-hidden>
|
||||
{display.map((v, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`droll droll-n-${v} ${settled ? 'is-settled' : 'is-rolling'}`}
|
||||
style={{ '--i': i } as CSSProperties}
|
||||
>
|
||||
{Array.from({ length: v }, (_, r) => (
|
||||
<span key={r} className="droll-rock" />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user