使用threejs实现第一人称视角的移动可以分为以下步骤:
- 初始化场景和相机
- 添加光源和地面等元素
- 监听鼠标和键盘事件
- 更新相机位置和角度
- 渲染场景
下面我们来逐步讲解。
1. 初始化场景和相机
在使用threejs之前,需要先在HTML中引入threejs库文件。建议使用在线CDN地址,代码如下:
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/r128/three.min.js"></script>
初始化场景和相机的代码如下:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 设置相机初始位置
camera.position.set(0, 0, 10);
在这里我们使用透视相机,即 THREE.PerspectiveCamera
,并设置了初始位置为 (0,0,10)。
2. 添加光源和地面等元素
为了更好的展现场景,我们需要给场景添加一个光源。一般使用 THREE.DirectionalLight
,代码如下:
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);
同时,我们为场景添加了一个地面 THREE.Mesh
,代码如下:
var geometry = new THREE.PlaneGeometry(1000, 1000);
var material = new THREE.MeshPhongMaterial({ color: 0xffffff });
var ground = new THREE.Mesh(geometry, material);
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
这里我们使用了一个平面几何体,并旋转了它的X轴,使其与地面平行。同时使用 THREE.MeshPhongMaterial
来设置材料颜色。
3. 监听鼠标和键盘事件
在实现第一人称视角移动时,我们需要监听用户的键盘和鼠标事件。例如按下键盘时,我们需要改变相机的位置和角度。
var moveForward = false;
var moveBackward = false;
var moveLeft = false;
var moveRight = false;
var onKeyDown = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // w
moveForward = true;
break;
case 37: // left arrow
case 65: // a
moveLeft = true;
break;
case 40: // down arrow
case 83: // s
moveBackward = true;
break;
case 39: // right arrow
case 68: // d
moveRight = true;
break;
}
};
var onKeyUp = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // w
moveForward = false;
break;
case 37: // left arrow
case 65: // a
moveLeft = false;
break;
case 40: // down arrow
case 83: // s
moveBackward = false;
break;
case 39: // right arrow
case 68: // d
moveRight = false;
break;
}
};
document.addEventListener('keydown', onKeyDown, false);
document.addEventListener('keyup', onKeyUp, false);
var onMouseMove = function (event) {
// 鼠标移动时更新相机角度
};
document.addEventListener('mousemove', onMouseMove, false);
在这里,我们监听了用户按下和松开键盘的事件,并设置了各个方向的移动状态。同时,我们也监听了用户鼠标移动的事件,并将相机角度和鼠标移动相关联。
下面是鼠标移动时的代码:
var onMouseMove = function (event) {
if (event.buttons === 1) {
var deltaX = event.movementX;
var deltaY = event.movementY;
// 根据鼠标移动量计算相机角度
camera.rotation.y += deltaX * 0.002;
camera.rotation.x += deltaY * 0.002;
// 限制相机角度
camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));
}
};
document.addEventListener('mousemove', onMouseMove, false);
在这里,我们根据鼠标移动量计算相机的角度,并限制相机角度在 [-π/2, π/2]
的范围内。
4. 更新相机位置和角度
在上述的鼠标和键盘事件中,我们已经监听到了用户的操作,现在需要根据这些操作来更新相机的位置和角度。
var clock = new THREE.Clock();
var update = function () {
var delta = clock.getDelta();
// 根据移动状态更新相机位置
if (moveForward) {
camera.translateZ(-2 * delta);
}
if (moveBackward) {
camera.translateZ(2 * delta);
}
if (moveLeft) {
camera.translateX(-2 * delta);
}
if (moveRight) {
camera.translateX(2 * delta);
}
// 渲染场景
renderer.render(scene, camera);
requestAnimationFrame(update);
};
update();
在这里,我们使用了一个 THREE.Clock
来计算时间差,以便于根据移动状态和时间来更新相机位置。同时,每次更新场景后,也需要渲染场景。
5. 完整代码
最终的完整代码如下。这里也包含了一些其它的控制,例如限制相机的移动范围等。
// 初始化场景和相机
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 10);
// 设置渲染器和尺寸
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 添加光源和地面等元素
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);
var geometry = new THREE.PlaneGeometry(1000, 1000);
var material = new THREE.MeshPhongMaterial({ color: 0xffffff });
var ground = new THREE.Mesh(geometry, material);
ground.rotation.x = -Math.PI / 2;
scene.add(ground);
// 监听鼠标和键盘事件
var moveForward = false;
var moveBackward = false;
var moveLeft = false;
var moveRight = false;
var onKeyDown = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // w
moveForward = true;
break;
case 37: // left arrow
case 65: // a
moveLeft = true;
break;
case 40: // down arrow
case 83: // s
moveBackward = true;
break;
case 39: // right arrow
case 68: // d
moveRight = true;
break;
}
};
var onKeyUp = function (event) {
switch (event.keyCode) {
case 38: // up arrow
case 87: // w
moveForward = false;
break;
case 37: // left arrow
case 65: // a
moveLeft = false;
break;
case 40: // down arrow
case 83: // s
moveBackward = false;
break;
case 39: // right arrow
case 68: // d
moveRight = false;
break;
}
};
document.addEventListener('keydown', onKeyDown, false);
document.addEventListener('keyup', onKeyUp, false);
var onMouseMove = function (event) {
if (event.buttons === 1) {
var deltaX = event.movementX;
var deltaY = event.movementY;
camera.rotation.y += deltaX * 0.002;
camera.rotation.x += deltaY * 0.002;
camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));
}
};
document.addEventListener('mousemove', onMouseMove, false);
// 更新相机位置和渲染场景
var clock = new THREE.Clock();
var update = function () {
var delta = clock.getDelta();
if (moveForward) {
camera.translateZ(-2 * delta);
}
if (moveBackward) {
camera.translateZ(2 * delta);
}
if (moveLeft) {
camera.translateX(-2 * delta);
}
if (moveRight) {
camera.translateX(2 * delta);
}
// 限制相机移动范围
camera.position.x = Math.max(-20, Math.min(20, camera.position.x));
camera.position.z = Math.max(-20, Math.min(20, camera.position.z));
renderer.render(scene, camera);
requestAnimationFrame(update);
};
update();
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用threejs实现第一人称视角的移动的问题(示例代码) - Python技术站