#javascript #three.js
#javascript #three.js
Вопрос:
Я только что перешел к трем.JS, и я столкнулся с проблемой. Я пытаюсь создать автомобиль, которым можно управлять с помощью клавиш со стрелками. До сих пор я заставлял ее двигаться вперед и назад, и колесики поворачиваются, когда вы нажимаете вверх (вперед) и вниз (назад). Итак, логично, что следующим шагом будет поворот. Однако именно здесь я обращаюсь к своей проблеме.
Я не могу понять, как сделать так, чтобы при нажатии клавиш со стрелками влево или вправо вращение колесиков медленно, постепенно увеличивалось, пока они не достигнут определенного значения, скажем, 45 для левого и -45 для правого.
У меня есть куб, вытянутый в форме преимущественно плоского прямоугольника, называемый шасси. У меня есть четыре колеса, Wheel_FL, FR, RL и RR. F означает передний, первый R означает задний, L означает левый, второй R означает правый. И Wheel_FL, и Wheel_FR имеют группу в качестве родительского элемента, который я буду использовать для поворота их влево или вправо, они действуют как стержень. Я не могу понять, как это сделать, я пытался искать ответ везде в течение последних нескольких дней, но безрезультатно. Если у кого-нибудь есть какие-либо идеи, пожалуйста, дайте мне знать! И если кому-то нужна дополнительная информация, пожалуйста, дайте мне знать!
Я также ищу способ затем, как только эта проблема с рулевым управлением будет устранена, повернуть само шасси таким образом, чтобы оно было реалистичным для поворота автомобиля.
Спасибо!
Если кому-то нужен пример, у меня есть один здесь.
Ответ №1:
Я могу помочь вам с первой частью вопроса:
Давайте назовем переменные: Wheel_FL, Wheel_FR, Group_FL, Group_FR;
. Каждое колесо вложено в соответствующую группу с Group_FL.add(Wheel_FL);
Итак, чтобы вращать колеса, вы, вероятно, сделали бы Wheel_FL.rotation.x = spinAngle;
или, возможно rotation.z
, основываясь на ориентации вашего ресурса. Теперь, чтобы повернуть влево / вправо, вам нужно повернуть контейнер Group
, чтобы он не мешал углу поворота: Group_FL.rotation.y = steerAngle;
Чтобы анимировать или изменять этот угол поворота, вы могли бы использовать MathUtils.lerp()
функцию (lerp расшифровывается как линейная интерполяция), которая принимает переменную и направляет ее к цели.
var Wheel_FL, Wheel_FR;
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();
Group_FL.add(Wheel_FL);
Group_FR.add(Wheel_FR);
var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;
function update() {
// Update wheel spin
Wheel_FL.rotation.x = spinAngle;
Wheel_FR.rotation.x = spinAngle;
// Tween steering angle towards target
steerAngle = MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);
// Rotate parent group around y-axis
Group_FL.rotation.y = steerAngle;
Group_FR.rotation.y = steerAngle;
}
function steerLeft() {
steerAngleTarget = Math.PI / 4; // 45 deg in radians
}
function steerRight() {
steerAngleTarget = - Math.PI / 4; // -45 deg in radians
}
Ниже я создал для вас рабочую демонстрацию. Используйте клавиши w-a-s-d для управления, ускорения и замедления:
var camera, scene, renderer, clock, container;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 100 );
camera.position.y = 10;
camera.position.z = 5;
camera.lookAt(0, 0, 0);
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xeeeeee );
scene.fog = new THREE.Fog( 0xcccccc, 100, 1500 );
clock = new THREE.Clock();
var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x222222, 1.5 );
hemiLight.position.set( 1, 1, 1 );
scene.add( hemiLight );
var floor = new THREE.Mesh(new THREE.PlaneBufferGeometry(10, 10), new THREE.MeshBasicMaterial({color: 0x999999}));
floor.rotation.x = -Math.PI/2;
scene.add(floor);
renderer = new THREE.WebGLRenderer();
renderer.setSize( container.offsetWidth, container.offsetHeight );
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener("keydown", onKeyPress);
window.addEventListener("keyup", onKeyRelease);
// Create wheels
var Wheel_FL = new THREE.Mesh(
new THREE.CylinderBufferGeometry(1, 1, 1, 8),
new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Wheel_FR = new THREE.Mesh(
new THREE.CylinderBufferGeometry(1, 1, 1, 8),
new THREE.MeshBasicMaterial({color: 0xffff00, wireframe: true})
);
var Group_FL = new THREE.Group();
var Group_FR = new THREE.Group();
// Set initial positions and rotations
Wheel_FL.position.y = 1;
Wheel_FR.position.y = 1;
Wheel_FL.rotation.z = Math.PI / 2;
Wheel_FR.rotation.z = Math.PI / 2;
// Add wheels to group, and position groups
Group_FL.add(Wheel_FL);
Group_FR.add(Wheel_FR);
Group_FL.position.x = -2;
Group_FR.position.x = 2;
scene.add(Group_FL);
scene.add(Group_FR);
var spinAngle = 0;
var steerAngle = 0;
var steerAngleTarget = 0;
// WASD to turn, accelerate, and decelerate
function onKeyPress(evt) {
switch(evt.key) {
case 'a':
steerAngleTarget = Math.PI / 6; // 45 deg in radians
break;
case 'd':
steerAngleTarget = - Math.PI / 6; // -45 deg in radians
break;
case 'w':
spinAngle = 0.01; // accelerate
break;
case 's':
spinAngle -= 0.01; // decelerate
break;
}
}
// Returns wheels to center
function onKeyRelease() {
steerAngleTarget = 0;
}
function onWindowResize() {
camera.aspect = container.offsetWidth / container.offsetHeight;
camera.updateProjectionMatrix();
renderer.setSize( container.offsetWidth, container.offsetHeight );
}
function update() {
// Update wheel spin
Wheel_FL.rotation.x -= spinAngle;
Wheel_FR.rotation.x -= spinAngle;
// Tween steering angle towards target
steerAngle = THREE.MathUtils.lerp(steerAngle, steerAngleTarget, 0.1);
// Rotate parent group around y-axis
Group_FL.rotation.y = steerAngle;
Group_FR.rotation.y = steerAngle;
requestAnimationFrame( update );
renderer.render(scene, camera);
}
update();
body, html {
background-color: #fff;
color: #222;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#container {
position: absolute;
top: 0;
width: 100%;
bottom: 0px;
}
<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<div id="container">
</div>