Created Dice Roller - Began work on character sheets
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
'use client';
|
||||
|
||||
import { useRef, useState, useCallback, useEffect } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import {
|
||||
initScene,
|
||||
Die,
|
||||
DieInstance,
|
||||
setDice,
|
||||
stopRenderLoop,
|
||||
initRenderLoop,
|
||||
getW,
|
||||
getD,
|
||||
} from '../lib/dicePhysics';
|
||||
|
||||
export interface RollResult {
|
||||
sides: number;
|
||||
value: number;
|
||||
}
|
||||
|
||||
export function useDiceRoller() {
|
||||
const mountRef = useRef<HTMLDivElement>(null);
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
const [isRolling, setIsRolling] = useState(false);
|
||||
const sceneInitRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mountRef.current || sceneInitRef.current) return;
|
||||
sceneInitRef.current = true;
|
||||
initScene(mountRef.current);
|
||||
initRenderLoop();
|
||||
|
||||
const timer = setTimeout(() => setIsReady(true), 300);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
stopRenderLoop();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const rollDice = useCallback(
|
||||
(pool: Record<number, number>): Promise<RollResult[]> => {
|
||||
return new Promise((resolve) => {
|
||||
const totalDice = Object.values(pool).reduce((a, b) => a + b, 0);
|
||||
if (totalDice === 0) {
|
||||
resolve([]);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsRolling(true);
|
||||
|
||||
const newDice: DieInstance[] = [];
|
||||
const W = getW();
|
||||
const D = getD();
|
||||
let idx = 0;
|
||||
const order = [20, 12, 10, 8, 6, 4];
|
||||
|
||||
order.forEach((sides) => {
|
||||
const count = pool[sides] || 0;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const die = new Die(sides);
|
||||
const side = idx % 2 === 0 ? -1 : 1;
|
||||
const x = side * (W - 0.8);
|
||||
const z = D - 1 - (idx % 3) * 1.1;
|
||||
const dir = new THREE.Vector3(
|
||||
-side * (9 + Math.random() * 4),
|
||||
0.5,
|
||||
-(6 + Math.random() * 4)
|
||||
);
|
||||
die.throwFrom(x, z, dir);
|
||||
die.pos.x -= side * idx * 0.15;
|
||||
newDice.push(die);
|
||||
idx++;
|
||||
}
|
||||
});
|
||||
|
||||
setDice(newDice, (completedDice) => {
|
||||
const results: RollResult[] = completedDice.map((d) => ({
|
||||
sides: d.sides,
|
||||
value: d.value ?? 0,
|
||||
}));
|
||||
setIsRolling(false);
|
||||
resolve(results);
|
||||
});
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return { mountRef, rollDice, isReady, isRolling };
|
||||
}
|
||||
Reference in New Issue
Block a user