feat: Implement enhanced interaction handling with move, build, and selection previews in Map3D component
This commit is contained in:
@@ -1101,10 +1101,60 @@ function Scene({ interactionMode, onInteraction }) {
|
||||
const selectedTurtleId = useTurtleStore((state) => state.selectedTurtleId);
|
||||
const selectTurtle = useTurtleStore((state) => state.selectTurtle);
|
||||
const worldBlocks = useTurtleStore((state) => state.worldBlocks || []);
|
||||
const sendCommand = useTurtleStore((state) => state.sendCommand);
|
||||
const setTurtleState = useTurtleStore((state) => state.setTurtleState);
|
||||
|
||||
// Mining areas state
|
||||
const [miningAreas, setMiningAreas] = useState([]);
|
||||
const [selectedAreaId, setSelectedAreaId] = useState(null);
|
||||
|
||||
// Interaction mode state
|
||||
const [moveTarget, setMoveTarget] = useState(null);
|
||||
const [buildPreview, setBuildPreview] = useState(null);
|
||||
const [selectionStart, setSelectionStart] = useState(null);
|
||||
const [selectionEnd, setSelectionEnd] = useState(null);
|
||||
const controlsRef = useRef();
|
||||
|
||||
// Handle block clicks from interaction modes
|
||||
const handleBlockClick = useCallback((event) => {
|
||||
if (event.type === 'move' && selectedTurtleId) {
|
||||
setMoveTarget(event.target);
|
||||
// Send the turtle to the clicked position
|
||||
setTurtleState(selectedTurtleId, 'moving', {
|
||||
target: event.target
|
||||
});
|
||||
// Clear preview after a moment
|
||||
setTimeout(() => setMoveTarget(null), 2000);
|
||||
if (onInteraction) onInteraction({ mode: 'move', target: event.target, turtleId: selectedTurtleId });
|
||||
} else if (event.type === 'build') {
|
||||
setBuildPreview(event.target);
|
||||
if (onInteraction) onInteraction({ mode: 'build', target: event.target });
|
||||
} else if (event.type === 'select') {
|
||||
if (!selectionStart) {
|
||||
setSelectionStart(event.block);
|
||||
setSelectionEnd(null);
|
||||
} else {
|
||||
setSelectionEnd(event.block);
|
||||
if (onInteraction) onInteraction({
|
||||
mode: 'select',
|
||||
start: selectionStart,
|
||||
end: event.block
|
||||
});
|
||||
// Reset after selection is complete
|
||||
setTimeout(() => {
|
||||
setSelectionStart(null);
|
||||
setSelectionEnd(null);
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
}, [selectedTurtleId, selectionStart, setTurtleState, onInteraction]);
|
||||
|
||||
// Disable orbit controls when in interactive mode
|
||||
useEffect(() => {
|
||||
if (controlsRef.current) {
|
||||
controlsRef.current.enabled = interactionMode === INTERACTION_MODE.LOOK;
|
||||
}
|
||||
}, [interactionMode]);
|
||||
|
||||
// Load mining areas
|
||||
useEffect(() => {
|
||||
@@ -1170,8 +1220,20 @@ function Scene({ interactionMode, onInteraction }) {
|
||||
infiniteGrid
|
||||
/>
|
||||
|
||||
{/* Render discovered blocks */}
|
||||
<WorldBlocks blocks={worldBlocks} />
|
||||
{/* Render discovered blocks with chunked rendering */}
|
||||
<WorldBlocks
|
||||
blocks={worldBlocks}
|
||||
interactionMode={interactionMode}
|
||||
selectedTurtleId={selectedTurtleId}
|
||||
onBlockClick={handleBlockClick}
|
||||
/>
|
||||
|
||||
{/* Interaction mode previews */}
|
||||
{moveTarget && <MoveTargetPreview position={moveTarget} />}
|
||||
{buildPreview && <BuildPreview position={buildPreview} />}
|
||||
{(selectionStart || selectionEnd) && (
|
||||
<SelectionArea start={selectionStart} end={selectionEnd || selectionStart} />
|
||||
)}
|
||||
|
||||
{/* Mining areas */}
|
||||
{miningAreas.map((area) => {
|
||||
@@ -1209,6 +1271,7 @@ function Scene({ interactionMode, onInteraction }) {
|
||||
|
||||
{/* Camera controls */}
|
||||
<OrbitControls
|
||||
ref={controlsRef}
|
||||
target={centerPoint}
|
||||
enableDamping
|
||||
dampingFactor={0.05}
|
||||
|
||||
Reference in New Issue
Block a user