feat: Add move and build preview components with selection area for enhanced interaction

This commit is contained in:
MayaTheShy
2026-02-20 02:18:16 -05:00
parent 1ef975cbae
commit dd2a877192

View File

@@ -983,8 +983,119 @@ function PlayerMarker({ player }) {
);
}
// Move target preview (ghost block showing where turtle will go)
function MoveTargetPreview({ position }) {
const meshRef = useRef();
useFrame((state) => {
if (meshRef.current) {
meshRef.current.position.y = position.y + Math.sin(state.clock.elapsedTime * 3) * 0.1;
meshRef.current.material.opacity = 0.3 + Math.sin(state.clock.elapsedTime * 2) * 0.15;
}
});
return (
<group>
<mesh ref={meshRef} position={[position.x, position.y, position.z]}>
<boxGeometry args={[0.8, 0.8, 0.8]} />
<meshStandardMaterial
color="#3b82f6"
transparent
opacity={0.4}
emissive="#3b82f6"
emissiveIntensity={0.5}
/>
</mesh>
<Text
position={[position.x, position.y + 1.2, position.z]}
fontSize={0.3}
color="#3b82f6"
anchorX="center"
anchorY="middle"
outlineWidth={0.04}
outlineColor="#000000"
>
MOVE HERE
</Text>
</group>
);
}
// Build preview (ghost block showing where block will be placed)
function BuildPreview({ position }) {
const meshRef = useRef();
useFrame((state) => {
if (meshRef.current) {
meshRef.current.material.opacity = 0.3 + Math.sin(state.clock.elapsedTime * 2) * 0.15;
}
});
return (
<mesh ref={meshRef} position={[position.x, position.y, position.z]}>
<boxGeometry args={[1.0, 1.0, 1.0]} />
<meshStandardMaterial
color="#22c55e"
transparent
opacity={0.4}
emissive="#22c55e"
emissiveIntensity={0.5}
wireframe={false}
/>
</mesh>
);
}
// Area selection wireframe for SELECT mode
function SelectionArea({ start, end }) {
if (!start || !end) return null;
const minX = Math.min(start.x, end.x);
const minY = Math.min(start.y, end.y);
const minZ = Math.min(start.z, end.z);
const maxX = Math.max(start.x, end.x);
const maxY = Math.max(start.y, end.y);
const maxZ = Math.max(start.z, end.z);
const width = maxX - minX + 1;
const height = maxY - minY + 1;
const depth = maxZ - minZ + 1;
const centerX = (minX + maxX) / 2;
const centerY = (minY + maxY) / 2;
const centerZ = (minZ + maxZ) / 2;
return (
<group position={[centerX, centerY, centerZ]}>
<lineSegments>
<edgesGeometry args={[new THREE.BoxGeometry(width, height, depth)]} />
<lineBasicMaterial color="#f59e0b" linewidth={2} />
</lineSegments>
<mesh>
<boxGeometry args={[width, height, depth]} />
<meshStandardMaterial
color="#f59e0b"
transparent
opacity={0.1}
side={THREE.DoubleSide}
/>
</mesh>
<Text
position={[0, height / 2 + 0.8, 0]}
fontSize={0.4}
color="#f59e0b"
anchorX="center"
anchorY="middle"
outlineWidth={0.04}
outlineColor="#000000"
>
{`${width}×${height}×${depth} Selection`}
</Text>
</group>
);
}
// Main scene component
function Scene() {
function Scene({ interactionMode, onInteraction }) {
const turtles = useTurtleStore((state) => state.getTurtleArray());
const players = useTurtleStore((state) => Object.values(state.players || {}));
const selectedTurtleId = useTurtleStore((state) => state.selectedTurtleId);