我正在学习Three.js,并且尝试着做我的第一场比赛:无尽的比赛。
我已经读过this article,目的是做一些非常相似的事情。 主角(英雄)是一个向“无限”方向滚动的蓝色球,必须避免在他面前逐渐出现的障碍。使用者可以通过将球向左或向右引导并跳跃来避免这些障碍(其想法是使用键盘,尤其是向左/向右箭头键和空格键跳跃)。
我想遵循本文的思想,但不想复制代码(我想理解)。 这是我到目前为止所做的:
let sceneWidth = window.innerWidth;
let sceneHeight = window.innerHeight;
let canvas;
let camera;
let scene;
let renderer;
let dom;
let sun;
let hero;
let ground;
let clock;
let spotLight;
let ambientLight;
init();
function init() {
createScene();
showHelpers();
update();
}
/**
* Set up scene.
*/
function createScene() {
clock = new THREE.Clock();
clock.start();
scene = new THREE.Scene();
window.scene = scene;
camera = new THREE.PerspectiveCamera(60, sceneWidth / sceneHeight, 0.1, 1000);
camera.position.set(0, 0, 0);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x333f47, 1);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
renderer.setSize(sceneWidth, sceneHeight);
canvas = renderer.domElement;
document.body.appendChild(canvas);
// const orbitControls = new THREE.OrbitControls(camera, canvas);
addGround();
addHero();
addLight();
camera.position.set(0, -1, 0.6);
camera.lookAt(new THREE.Vector3(0, 0, 0));
window.addEventListener("resize", onWindowResize, false);
}
/**
* Show helper.
*/
function showHelpers() {
const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);
const spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);
}
/**
* Add ground to scene.
*/
function addGround() {
const geometry = new THREE.PlaneGeometry(1, 4);
const material = new THREE.MeshLambertMaterial({
color: 0xcccccc,
side: THREE.DoubleSide
});
ground = new THREE.Mesh(geometry, material);
ground.position.set(0, 1, 0);
ground.receiveShadow = true;
scene.add(ground);
}
/**
* Add hero to scene.
*/
function addHero() {
var geometry = new THREE.SphereGeometry(0.03, 32, 32);
var material = new THREE.MeshLambertMaterial({
color: 0x3875d8,
side: THREE.DoubleSide
});
hero = new THREE.Mesh(geometry, material);
hero.receiveShadow = true;
hero.castShadow = true;
scene.add(hero);
hero.position.set(0, -0.62, 0.03);
}
/**
* Add light to scene.
*/
function addLight() {
// spot light
spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(2, 30, 0);
spotLight.angle = degToRad(10);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 45;
scene.add(spotLight);
// ambient light
ambientLight = new THREE.AmbientLight(0x303030, 2);
scene.add(ambientLight);
}
/**
* Call game loop.
*/
function update() {
render();
requestAnimationFrame(update);
}
/**
* Render the scene.
*/
function render() {
renderer.render(scene, camera);
}
/**
* On window resize, render again the scene.
*/
function onWindowResize() {
sceneHeight = window.innerHeight;
sceneWidth = window.innerWidth;
renderer.setSize(sceneWidth, sceneHeight);
camera.aspect = sceneWidth / sceneHeight;
camera.updateProjectionMatrix();
}
/**
* Degree to radiants
*/
function degToRad(degree) {
return degree * (Math.PI / 180);
}
<script src="https://threejs.org/build/three.min.js"></script>
(JSFiddle)
我遇到几个问题,首先是物体和摄像机的位置。
我希望能够定位该平面,以便将次侧面定位在屏幕的开头(因此,整个平面必须是可见的,不能有隐藏的部分)。
我希望将球水平放置在地板的中间,垂直放置在地板的开始处(简而言之,如图所示),并将阴影投射到飞机上。每个对象必须将阴影投影到平面上。 我使用的是聚光灯和兰伯特材料,因此阴影应该存在,但没有阴影。为什么?
我什至不知道如何放置物体。
我知道点(0, 0, 0)
是屏幕的中心。
我希望地面位于y=0
,所有其他对象都位于上方,就好像它们在静止一样。
我的代码有效,但是我不知道是否有更好的方法来处理对象放置。
我还可以通过分配球体半径1
而不是0.03
来简化我的生活,然后使场景“更小”以缩小相机以将相机移开(我认为这是窍门)
所以,我需要正确设置场景的帮助。
这是我在ThreeJs中的第一个应用程序,欢迎任何建议!
编辑1
我将camera.lookAt(new THREE.Vector3(0, 0, 0));
更改为camera.lookAt(new THREE.Vector3(0, 0, -5));
,并添加了spotLight.lookAt(new THREE.Vector3(0, 0, -5));
。
这是结果:
不完全是我想要的...
答案 0 :(得分:1)
您正确地将平面和球体在y轴上设置为0。您遇到的问题是,您告诉相机在进行操作
时直视(0,0,0) <ul>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn">Monitor</a>
<div class="dropdown-content">
<a href="Index.html">Tube 1</a>
<a href="#">Tube 2</a>
</div>
</li>
<li><a href="Developer.html">Input</a></li>
<li><a href="Information.html">Information</a></li>
<li style="float:right" id="Credit"><a>Text</a></li>
</ul>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
<p>p</p>
这样您就可以使球完全居中。您应该做的就是告诉相机看起来要比球体稍微领先一点。您必须调整值,但是类似的事情应该可以解决问题:
camera.lookAt(0, 0, 0);
此外,您的聚光灯指向正前方。当您将其放在(2,30,0)时,其效果会消失。您需要将其指向您想要的位置:
camera.lookAt(0, 0, -5);