一开始还就迷茫呢碰撞检测比较难,后来发现了physi.js。
也是在看three.js看到的一个库,用了web worker实现各种复杂的计算。
先点击这里看效果,手机电脑支持web worker(一般都支持)的都可以运行
初次加载看起来快,实际一个用于计算的ammo.js也有1.2M,只是他在后台加载。所以可能得等一会儿。
这个本应该有个onload的,不过目前还没有发现这个函数,之后有机会在探索。
思路便是:创造一个物理舞台,摄像头和渲染器和之前一样,加一个物理平面(带摩擦和弹性),加一个普通cube并来回运动,监听click事件,click时获取普通cube的位置并创造一个物理cube,物理cube便会往下掉,加一个计分。
下面是具体代码,js文件的话在下面的路径可以找到
http://test.ganjiacheng.cn/3d/learning-threejs/libs/xxx.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test3d6</title>
<style type="text/css">
body{
margin: 0;
overflow: hidden;
}
#stats{
position: absolute;
left: 0;
top: 0;
}
#grade{
position: absolute;
left: 50%;
margin-left: -28px;
top: 0;
}
</style>
</head>
<body>
<div id="stats"></div>
<div id="grade">0</div>
<div id="webgl"></div>
<script type="text/javascript" src="learning-threejs/libs/three.js"></script>
<script type="text/javascript" src="learning-threejs/libs/stats.js"></script>
<script type="text/javascript" src="learning-threejs/libs/physi.js"></script>
<script type="text/javascript">
var scene;
function init(){
var stats=initStats();
Physijs.scripts.worker='learning-threejs/libs/physijs_worker.js';
var scene=new Physijs.Scene();
scene.setGravity(new THREE.Vector3(0,-50,0));
var camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);
camera.position.set(-30,40,40);
camera.lookAt(scene.position);
var renderer=new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.shadowMapEnable=true;
var ground_material=Physijs.createMaterial(new THREE.MeshLambertMaterial({color:0xffffff}),0.9,0.3);
var planeGeometry=new Physijs.BoxMesh(new THREE.BoxGeometry(10,1,10),ground_material,0)
scene.add(planeGeometry);
function addPhyCube(x=0,y=0,z=0){
var cubeGeometry=new THREE.BoxGeometry(10,2,10);
var cube=new Physijs.BoxMesh(cubeGeometry,Physijs.createMaterial(new THREE.MeshLambertMaterial({color:0xffffff*Math.random()}),1,0));
cube.position.set(x,y,z);
scene.add(cube);
}
function addNormalCube(x=0,y=8,z=0){
var cubeGeometry=new THREE.BoxGeometry(10,2,10);
var cubeMaterial=new THREE.MeshLambertMaterial({color:0xff0000});
var cube=new THREE.Mesh(cubeGeometry,cubeMaterial);
cube.position.set(x,y,z);
scene.add(cube);
}
var maxy=0;
var NorNum=2;
var time=0
function refreshGrade(){
if(time==0 && stats.domElement.textContent[0]==6){
document.getElementById("webgl").onmousedown=function(){
addPhyCube(scene.children[NorNum].position.x,scene.children[NorNum].position.y,scene.children[NorNum].position.z);
time=2;
}
time=1;
}else if(time==1){
document.getElementById("grade").innerHTML="start";
}else if(time==2){
var len=scene.children.length;
var maxy=0;
for(var i=NorNum+1;i<len;i++){
maxy=scene.children[i].position.y>-2&&Math.abs(scene.children[i].position.z)<15?maxy+1:maxy;
}
camera.position.y=maxy*2+40;
scene.children[NorNum].position.y=maxy*2+5;
document.getElementById("grade").innerHTML="score:"+maxy;
}else{
document.getElementById("grade").innerHTML="waiting......";
}
}
var spotLight=new THREE.SpotLight(0xffffff);
spotLight.position.set(-40,60,0);
scene.add(spotLight);
spotLight.castShadow=true;
document.getElementById("webgl").appendChild(renderer.domElement);
addNormalCube(0,8,-20);
renderer.render(scene,camera);
var step=0;
function rendererScene(){
stats.update();
refreshGrade();
last=scene.children.length-1;
step+=0.05;
scene.children[NorNum].position.z+=Math.sin(step);
requestAnimationFrame(rendererScene);
renderer.render(scene,camera);
scene.simulate();
}
function initStats(){
var stats=new Stats();
stats.setMode(0);
document.getElementById("stats").appendChild(stats.domElement);
return stats;
}
rendererScene();
}
window.onload=init;
</script>
</body>
</html>
效果展示:
版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下
支付宝打赏
微信打赏