Three.js 入门认识基础自学
Three.js 认识
初级使用,无须深究原理、根着文档调用接口 、new对象 就OK
编辑器选择 vscode 接着安装插件 live server 然后右击文件 选择open with live server 打开
code
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="JS/three.js"></script>
<script src="JS/MTLLoader.js"></script>
<script src="JS/OBJLoader.js"></script>
</head>
<body>
<script>
//创建场景,相机,渲染器,网格
var scene,camera,renderer,mesh;
var meshfloor,ambientLight,light;
var crate,crateTexture,crateNormalMap,crateBumpMap;
//diffuse texture 漫反射贴图 normal texture 法线贴图 Bump Mapping 凹凸贴图
var keyboard={};
//是否射击的变量
var player={height:1.8,speed:0.2,turnSpeed:Math.PI*0.05,canShoot:0};
// 创建一个对象,用于存放加载场景所需的所有内容
var loadingScreen={
scene:new THREE.Scene(),
camera:new THREE.PerspectiveCamera(90,1280/720,0.1,100),
box:new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshBasicMaterial({
color:0x4444ff,
wireframe:true
})
)
}
//创建一个加载管理器
var loadingManager=null;
//创建下载是否完成的布尔值
var Resource_Loaded=false;
// 模型索引
var models={
female:{
obj:"Models/female02.obj",
mtl:"Models/female02.mtl",
mesh:null
} ,
zombie:{
obj:"Models/zombie.obj",
mtl:"Models/zombie.mtl",
mesh:null
},
zombieBlue:{
obj:"Models/zombie_blue.obj",
mtl:"Models/zombie_blue.mtl",
mesh:null
},
//添加武器模型及材质
gun:{
obj:"Models/gun.obj",
mtl:"Models/gun.mtl",
mesh:null,
castShadow:false
}
}
// 网格索引
var meshes={};
//创建一个数组来保存子弹
var bullets=[];
//设置加载场景对象的一些属性
loadingScreen.box.position.set(0,0,5);
loadingScreen.camera.lookAt(loadingScreen.box.position);
loadingScreen.scene.add(loadingScreen.box);
scene=new THREE.Scene();
camera=new THREE.PerspectiveCamera(90,1280/720,0.1,100);
//实例化加载管理器
loadingManager=new THREE.LoadingManager();
//加载过程
loadingManager.onProgress=function(item,loaded,total){
console.log(item,loaded,total);
}
//加载完成
loadingManager.onLoad=function() {
console.log("已下载所有资源!");
Resource_Loaded=true;
onResourceLoaded();
}
mesh=new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
//new THREE.SphereGeometry(1,20,20),
//MeshBasicMaterial 对光照无反应
new THREE.MeshPhongMaterial({color:0x0000ff,wireframe:false})
// 0xff0000 红色
// 0x00ff00 绿色,
// 0x0000ff 蓝色.
// 0xffffff 黑色
// 0x000000 白色
)
mesh.receiveShadow=true;
mesh.castShadow=true;
mesh.position.y+=1;
meshfloor=new THREE.Mesh(
new THREE.PlaneGeometry(20,20,10,10),
new THREE.MeshPhongMaterial({color:0xffffff,wireframe:false})
)
meshfloor.rotation.x -=Math.PI/2;
meshfloor.receiveShadow=true;
//加载贴图 在参数中添加加载管理器
var textureLoader=new THREE.TextureLoader(loadingManager);
crateTexture=textureLoader.load("Img/01.jpg");
crateNormalMap=textureLoader.load("Img/02.jpg");
crateBumpMap=textureLoader.load("Img/03.jpg");
crate=new THREE.Mesh(
new THREE.BoxGeometry(3,3,3),
new THREE.MeshPhongMaterial({
color:0xffffff,
map:crateTexture,
normalMap:crateNormalMap,
bumpMap:crateBumpMap
})
)
crate.position.set(2.5,3/2,2.5);
crate.receiveShadow=true;
crate.castShadow=true;
scene.add(mesh);
scene.add(meshfloor);
scene.add(crate);
// 加载模型
for(var _key in models){
(function(key){
//加载模型和材质
var mtlLoader=new THREE.MTLLoader(loadingManager);
mtlLoader.load(models[key].mtl,function(materials){
materials.preload();
var objLoader=new THREE.OBJLoader(loadingManager);
objLoader.setMaterials(materials);
objLoader.load(models[key].obj,function(mesh){
//给加载的人物模型加上阴影
mesh.traverse(function(node){
if(node instanceof THREE.Mesh){
if('castShadow' in models[key])
node.castShadow=models[key].castShadow;
else
node.castShadow=true;
if('receiveShadow' in models[key])
node.receiveShadow=models[key].receiveShadow;
else
node.receiveShadow=true;
//node.castShadow=true;
//node.receiveShadow=true;
}
});
models[key].mesh=mesh;
});
});
})(_key)
}
//环境光
ambientLight=new THREE.AmbientLight(0xffffff,0.5);
scene.add(ambientLight);
//点光
light=new THREE.PointLight(0xffffff,0.8,18);
light.position.set(0,2,0);
light.castShadow=true;
light.shadow.camera.near=0.1;
light.shadow.camera.far=25;
scene.add(light);
camera.position.set(0,player.height,-5);
camera.lookAt(new THREE.Vector3(0,player.height,0))
renderer=new THREE.WebGLRenderer()
renderer.setSize(1280,720);
//给渲染器添加阴影效果
renderer.shadowMap.enabled=true;
renderer.shadowMap.type=THREE.BasicShadowMap;
//把画面插入HTML中的body标签下显示
document.body.appendChild(renderer.domElement);
animate();
function onResourceLoaded(){
// 将模型克隆到网格中
meshes["female"]=models.female.mesh.clone();
meshes["female2"]=models.female.mesh.clone();
meshes["zombie"]=models.zombie.mesh.clone();
meshes["zombie2"]=models.zombieBlue.mesh.clone();
meshes["female"].position.set(-5,0,4);
meshes["female"].scale.set(0.03,0.03,0.03);
meshes["female"].rotation.y = -Math.PI/1;
scene.add (meshes["female"]);
meshes["female2"].position.set(-8,0,4);
meshes["female2"].scale.set(0.03,0.03,0.03);
meshes["female2"].rotation.y = -Math.PI/1;
scene.add(meshes["female2"]);
meshes["zombie"].position.set(-5,0,6);
meshes["zombie"].scale.set(0.08,0.08,0.08);
meshes["zombie"].rotation.y = -Math.PI/1;
scene.add (meshes["zombie"]);
meshes["zombie2"].position.set(-1,0,6);
meshes["zombie2"].scale.set(0.08,0.08,0.08);
meshes["zombie2"].rotation.y = -Math.PI/1;
scene.add(meshes["zombie2"]);
//玩家的武器
meshes["gun"]=models.gun.mesh.clone();
meshes["gun"].position.set(-1,1,10);
meshes["gun"].scale.set(15,15,15);
//meshes["zombie2"].rotation.y = -Math.PI/1;
scene.add(meshes["gun"]);
}
function animate() {
// 在加载资源时运行此块代码
if(Resource_Loaded==false){
requestAnimationFrame(animate);
loadingScreen.box.position.x-=0.05;
if(loadingScreen.box.position.x<-10)
loadingScreen.box.position.x=10;
loadingScreen.box.position.y=Math.sin(loadingScreen.box.position.x);
renderer.render(loadingScreen.scene,loadingScreen.camera);
return;
}
requestAnimationFrame(animate);
var time=Date.now()*0.0005;
mesh.rotation.x+=0.01;
mesh.rotation.y+=0.02;
renderer.render(scene,camera);
//子弹更新位置
//删除消失的子弹
for(var index=0; index<bullets.length;index+=1){
if(bullets[index]===undefined) continue;
if(bullets[index].alive==false){
bullets.splice(index,1);
continue;
}
bullets[index].position.add(bullets[index].velocity);
}
//键盘移动输入
if(keyboard[87]){ //W key
//Math.sin(x) x 的正玄值。返回值在 -1.0 到 1.0 之间;
//Math.cos(x) x 的余弦值。返回的是 -1.0 到 1.0 之间的数;
camera.position.x+=Math.sin(camera.rotation.y)*player.speed;
camera.position.z+=Math.cos(camera.rotation.y)*player.speed;
}
if(keyboard[83]){ //S key
camera.position.x-=Math.sin(camera.rotation.y)*player.speed;
camera.position.z-=Math.cos(camera.rotation.y)*player.speed;
}
if(keyboard[65]){ //A key
camera.position.x+=Math.sin(camera.rotation.y+Math
.PI/2)*player.speed;
camera.position.z-=Math.cos(camera.rotation.y+Math.PI)*player.speed;
}
if(keyboard[68]){ //D key
camera.position.x+=Math.sin(camera.rotation.y-Math
.PI/2)*player.speed;
camera.position.z-=Math.cos(camera.rotation.y-Math.PI)*player.speed;
}
if(keyboard[37]) { //左边箭头键
camera.rotation.y-=player.turnSpeed;
}
if(keyboard[39]) { //右边箭头键
camera.rotation.y+=player.turnSpeed;
}
//射击
if(keyboard[32] && player.canShoot<=0) { //空格键
//创建一个子弹的网格和几何体
var bullet =new THREE.Mesh(
new THREE.SphereGeometry(0.05,8,8),
new THREE.MeshBasicMaterial({color:0xfffffff})
)
//子弹产生的位置
bullet.position.set(
meshes["gun"].position.x,
meshes["gun"].position.y+0.025,
meshes["gun"].position.z
)
//子弹的速度
bullet.velocity=new THREE.Vector3(
-Math.sin(camera.rotation.y),
0,
Math.cos(camera.rotation.y)
)
//到一定时间后让子弹消失
bullet.alive=true;
setTimeout(function(){
bullet.alive=false;
scene.remove(bullet);
},1000);
bullets.push(bullet);
scene.add(bullet);
player.canShoot=30;
}
if(player.canShoot>0)
player.canShoot-=1;
//var time=Date().now()*0.0005;
//将枪放在相机前面
meshes["gun"].position.set(
camera.position.x-Math.sin(camera.rotation.y+Math
.PI/6)*0.75,
camera.position.y-0.4+Math
.sin(time*4+camera.position.x+camera.position.z)*0.01,
camera.position.z+Math
.cos(camera.rotation.y+Math
.PI/6)
);
meshes["gun"].rotation.set(
camera.rotation.x,
camera.rotation.y-Math.PI,
camera.rotation.z
);
}
function keyDown(event){
keyboard[event.keyCode]=true;
}
function keyUp(event) {
keyboard[event.keyCode]=false;
}
window.addEventListener('keydown',keyDown);
window.addEventListener(('keyup'),keyUp);
</script>
</body>
</html>
个人博客停止维护,部分博客转载到这
- 彼特城
- 2020-11-04 15:22:41
本作品采用《CC 协议》,转载必须注明作者和本文链接