ขนาดวิดีโอ: 1280 X 720853 X 480640 X 360
แสดงแผงควบคุมโปรแกรมเล่น
เล่นอัตโนมัติ
เล่นใหม่
import React, { useState, useEffect, useRef } from "react";import { Canvas, useFrame } from "@react-three/fiber";import { Box, OrbitControls, Plane } from "@react-three/drei";import * as THREE from "three";const DynamicCube = ({ staticCubes, onCollision, onProximity }) => { const [position, setPosition] = useState([0, 0.5, 0]); // Dynamic cube's position const dynamicRef = useRef(); const raycaster = useRef(new THREE.Raycaster()); // Single Raycaster instance const directions = [ new THREE.Vector3(1, 0, 0), // Right new THREE.Vector3(-1, 0, 0), // Left new THREE.Vector3(0, 0, 1), // Forward new THREE.Vector3(0, 0, -1), // Backward ]; useEffect(() => { const handleKeyDown = (event) => { setPosition((prev) => { const [x, y, z] = prev; switch (event.key) { case "w": // Move forward (z-axis) case "ArrowUp": // Arrow Up (move forward) return [x, y, z - 0.5]; case "s": // Move backward (z-axis) case "ArrowDown": // Arrow Down (move backward) return [x, y, z + 0.5]; case "a": // Move left (x-axis) case "ArrowLeft": // Arrow Left (move left) return [x - 0.5, y, z]; case "d": // Move right (x-axis) case "ArrowRight": // Arrow Right (move right) return [x + 0.5, y, z]; default: return prev; } }); }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, []); useFrame(() => { if (!dynamicRef.current) return; // Get the dynamic cube's position const dynamicPosition = new THREE.Vector3(...position); // Iterate through each direction for raycasting directions.forEach((direction) => { raycaster.current.set(dynamicPosition, direction); const intersects = raycaster.current.intersectObjects( staticCubes.map((cube) => cube.ref.current) ); // Handle collision (direct intersection) if (intersects.length > 0 && intersects[0].distance cube.ref.current === intersects[0].object ); if (collidedObject) { onCollision(collidedObject.id); } } // Handle proximity (objects within a range) if (intersects.length > 0 && intersects[0].distance cube.ref.current === intersects[0].object ); if (nearbyObject) { onProximity(nearbyObject.id); } } }); }); return ( );};const StaticCube = React.forwardRef(({ id, position }, ref) => ( ));const Ground = () => { return ( );};const App = () => { const staticCubes = [ { id: "Cube 1", position: [2, 0.5, 4], ref: React.createRef() }, { id: "Cube 2", position: [10, 0.5, 4], ref: React.createRef() }, ]; const handleCollision = (id) => { console.log(`Collision detected with: ${id}`); // Collision logs }; const handleProximity = (id) => { console.log(`Proximity detected around: ${id}`); // Proximity logs }; return ( {/* Lights */} {/* OrbitControls */} {/* Ground */} {/* Static Cubes */} {staticCubes.map((cube) => ( ))} {/* Dynamic Cube */} );};export default App;
import React, { useState, useEffect, useRef } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { Box, OrbitControls, Plane } from "@react-three/drei";
import * as THREE from "three";
const DynamicCube = ({ staticCubes, onCollision, onProximity }) => {
const [position, setPosition] = useState([0, 0.5, 0]); // Dynamic cube's position
const dynamicRef = useRef();
const raycaster = useRef(new THREE.Raycaster()); // Single Raycaster instance
const directions = [
new THREE.Vector3(1, 0, 0), // Right
new THREE.Vector3(-1, 0, 0), // Left
new THREE.Vector3(0, 0, 1), // Forward
new THREE.Vector3(0, 0, -1), // Backward
];
useEffect(() => {
const handleKeyDown = (event) => {
setPosition((prev) => {
const [x, y, z] = prev;
switch (event.key) {
case "w": // Move forward (z-axis)
case "ArrowUp": // Arrow Up (move forward)
return [x, y, z - 0.5];
case "s": // Move backward (z-axis)
case "ArrowDown": // Arrow Down (move backward)
return [x, y, z + 0.5];
case "a": // Move left (x-axis)
case "ArrowLeft": // Arrow Left (move left)
return [x - 0.5, y, z];
case "d": // Move right (x-axis)
case "ArrowRight": // Arrow Right (move right)
return [x + 0.5, y, z];
default:
return prev;
}
});
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
useFrame(() => {
if (!dynamicRef.current) return;
// Get the dynamic cube's position
const dynamicPosition = new THREE.Vector3(...position);
// Iterate through each direction for raycasting
directions.forEach((direction) => {
raycaster.current.set(dynamicPosition, direction);
const intersects = raycaster.current.intersectObjects(
staticCubes.map((cube) => cube.ref.current)
);
// Handle collision (direct intersection)
if (intersects.length > 0 && intersects[0].distance cube.ref.current === intersects[0].object
);
if (collidedObject) {
onCollision(collidedObject.id);
}
}
// Handle proximity (objects within a range)
if (intersects.length > 0 && intersects[0].distance cube.ref.current === intersects[0].object
);
if (nearbyObject) {
onProximity(nearbyObject.id);
}
}
});
});
return (
);
};
const StaticCube = React.forwardRef(({ id, position }, ref) => (
));
const Ground = () => {
return (
);
};
const App = () => {
const staticCubes = [
{ id: "Cube 1", position: [2, 0.5, 4], ref: React.createRef() },
{ id: "Cube 2", position: [10, 0.5, 4], ref: React.createRef() },
];
const handleCollision = (id) => {
console.log(`Collision detected with: ${id}`); // Collision logs
};
const handleProximity = (id) => {
console.log(`Proximity detected around: ${id}`); // Proximity logs
};
return (
{/* Lights */}
{/* OrbitControls */}
{/* Ground */}
{/* Static Cubes */}
{staticCubes.map((cube) => (
))}
{/* Dynamic Cube */}
);
};
export default App;