Короче парни не шарю в коде, развиваю ютубчик, и ищу разные ниши в которые можно влететь. Теперь по теме, наткнулся на такой канал, ему +- месяц и там очень интересные залипательные видео , пробовал на P5.js через курсор сделать, но все ламалось и не получалось, может кто поможет)?
Конечно, teapays! Вот простой пример кода для создания 3D симуляции шариков с использованием Three.js и Cannon.js. Этот пример включает комментарии, которые объясняют каждый шаг. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Ball Simulation</title> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/cannon-es/0.18.0/cannon-es.js"></script> <script> // Создаем сцену const scene = new THREE.Scene(); // Создаем камеру const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // Создаем рендерер const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Добавляем свет const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5).normalize(); scene.add(light); // Создаем физический мир const world = new CANNON.World(); world.gravity.set(0, -9.82, 0); // Устанавливаем гравитацию // Создаем физическое тело для пола const groundBody = new CANNON.Body({ mass: 0, // Масса 0 означает, что объект неподвижен shape: new CANNON.Plane(), }); groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0); world.addBody(groundBody); // Создаем плоскость в Three.js для визуализации пола const groundGeometry = new THREE.PlaneGeometry(10, 10); const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const groundMesh = new THREE.Mesh(groundGeometry, groundMaterial); groundMesh.rotation.x = -Math.PI / 2; scene.add(groundMesh); // Создаем массив для хранения шариков const balls = []; const ballBodies = []; // Функция для создания шарика function createBall() { // Создаем геометрию и материал для шарика const ballGeometry = new THREE.SphereGeometry(0.2, 32, 32); const ballMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 }); const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial); scene.add(ballMesh); balls.push(ballMesh); // Создаем физическое тело для шарика const ballShape = new CANNON.Sphere(0.2); const ballBody = new CANNON.Body({ mass: 1 }); ballBody.addShape(ballShape); ballBody.position.set(0, 2, 0); world.addBody(ballBody); ballBodies.push(ballBody); } // Создаем один шарик createBall(); // Анимация function animate() { requestAnimationFrame(animate); // Обновляем физический мир world.step(1 / 60); // Обновляем позицию и вращение шариков for (let i = 0; i < balls.length; i++) { balls[i].position.copy(ballBodies[i].position); balls[i].quaternion.copy(ballBodies[i].quaternion); } // Рендерим сцену renderer.render(scene, camera); } animate(); </script> </body> </html> HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Ball Simulation</title> <style> body { margin: 0; } canvas { display: block; } </style> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/cannon-es/0.18.0/cannon-es.js"></script> <script> // Создаем сцену const scene = new THREE.Scene(); // Создаем камеру const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // Создаем рендерер const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Добавляем свет const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5, 5, 5).normalize(); scene.add(light); // Создаем физический мир const world = new CANNON.World(); world.gravity.set(0, -9.82, 0); // Устанавливаем гравитацию // Создаем физическое тело для пола const groundBody = new CANNON.Body({ mass: 0, // Масса 0 означает, что объект неподвижен shape: new CANNON.Plane(), }); groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0); world.addBody(groundBody); // Создаем плоскость в Three.js для визуализации пола const groundGeometry = new THREE.PlaneGeometry(10, 10); const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const groundMesh = new THREE.Mesh(groundGeometry, groundMaterial); groundMesh.rotation.x = -Math.PI / 2; scene.add(groundMesh); // Создаем массив для хранения шариков const balls = []; const ballBodies = []; // Функция для создания шарика function createBall() { // Создаем геометрию и материал для шарика const ballGeometry = new THREE.SphereGeometry(0.2, 32, 32); const ballMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 }); const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial); scene.add(ballMesh); balls.push(ballMesh); // Создаем физическое тело для шарика const ballShape = new CANNON.Sphere(0.2); const ballBody = new CANNON.Body({ mass: 1 }); ballBody.addShape(ballShape); ballBody.position.set(0, 2, 0); world.addBody(ballBody); ballBodies.push(ballBody); } // Создаем один шарик createBall(); // Анимация function animate() { requestAnimationFrame(animate); // Обновляем физический мир world.step(1 / 60); // Обновляем позицию и вращение шариков for (let i = 0; i < balls.length; i++) { balls[i].position.copy(ballBodies[i].position); balls[i].quaternion.copy(ballBodies[i].quaternion); } // Рендерим сцену renderer.render(scene, camera); } animate(); </script> </body> </html> Этот код создает простую сцену с одним шариком, который падает на плоскость под действием гравитации. Если у тебя возникнут вопросы или нужно что-то изменить, дай знать!