如何使用three.js 制作一个三维的推箱子游戏
今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏。在线案例请点击
要制作一个推箱子游戏,正常要有以下4个步骤
- 定义一些数组,要有开始箱子数组、结束箱子数组、地面数组还有墙面数组,有这四个数组就可以组成一个关卡。
- 根据数组初始化地面墙面箱子和目标地点标志物。
- 使用FirstPersonControls控制器,控制相机移动,根据地面箱子和墙面算出可移动区域。
- 根据相机正对箱子时,用鼠标点击箱子,控制箱子移动,并做成功性校验。
下面我们上代码分析代码
1.定义数组
这四个数组分别是墙的数组、地面的数组、箱子初始位置数组和目标数组。
wallArr=[[0,0],[1,0],[2,0],[3,0],[3,1],[4,1],[4,2],[4,3],[5,3],[5,4],[5,5],[5,6],[4,6],[3,6],[2,6],[1,6],[0,6],[0,5],[0,4],[0,3],[0,2],[0,1]] scopeArr=[[1,1],[2,1],[1,2],[2,2],[3,2],[1,3],[2,3],[1,4],[4,4],[1,5],[2,5],[3,5],[4,5]]; boxArr=[[3,3],[2,4],[3,4]]; targetArr=[[2,2],[1,3],[2,3]];
2.根据箱子初始位置数组初始化箱子
initBox(){ vartextureBox=newTHREE.TextureLoader().load("/static/images/base/crate.png"); if(boxGroup){ scene.remove(boxGroup) } boxGroup=newTHREE.Group(); boxGroup.name='box_group' boxArr.forEach(d=>{ varboxGeom=newTHREE.BoxGeometry(40,40,40); varboxMate=[]; boxGeom.faces.forEach(d=>boxMate.push(newTHREE.MeshBasicMaterial({map:textureBox}))) varboxMesh=newTHREE.Mesh(boxGeom,boxMate); boxMesh.position.set(d[0]*40-20,20,d[1]*40-20); boxMesh.name='box'; boxGroup.add(boxMesh); }) scene.add(boxGroup); //判断是否赢得比赛 this.isWinner(boxArr,targetArr) }
3.根据地面数组初始化地面
initGround(){ vartextureGround=newTHREE.TextureLoader().load("/static/images/wall/plaster.jpg",()=>{this.loaded_num--}); vartextureGroundNormal=newTHREE.TextureLoader().load("/static/images/wall/plaster-normal.jpg",()=>{this.loaded_num--}); vartextureGroundSpecular=newTHREE.TextureLoader().load("/static/images/wall/plaster-diffuse.jpg",()=>{this.loaded_num--}); textureGround.wrapS=textureGround.wrapT=THREE.RepeatWrapping; textureGround.repeat.set(50,50); textureGroundNormal.wrapS=textureGroundNormal.wrapT=THREE.RepeatWrapping; textureGroundNormal.repeat.set(50,50); varmaterialGround=newTHREE.MeshPhongMaterial({ map:textureGround }) materialGround.normalMap=textureGroundNormal; materialGround.specularMap=textureGroundSpecular; varground=newTHREE.Mesh(newTHREE.PlaneGeometry(1000,1000,1,1),materialGround); ground.rotation.x=-Math.PI/2; scene.add(ground); }
4.根据墙数组初始化地面
initWall(){ varnormal=newTHREE.TextureLoader().load("/static/images/wall/stone.jpg",()=>{this.loaded_num--}); varbump=newTHREE.TextureLoader().load("/static/images/wall/stone-bump.jpg",()=>{this.loaded_num--}); wallArr.forEach(d=>{ varwallBox=newTHREE.BoxGeometry(40,40,40); varmaterial=newTHREE.MeshPhongMaterial({ map:normal, bumpMap:bump, bumpScale:1 }) varwall=newTHREE.Mesh(wallBox,material); wall.position.x=d[0]*40-20; wall.position.y=20; wall.position.z=d[1]*40-20; scene.add(wall); }) }
5.根据目标数组初始化目标物
initTarget(){ letobjLoader=newOBJLoader(); objLoader.setPath("/static/images/texture/hongqi/"); objLoader.load('hongqi.obj',(object)=>{ this.loaded_num--; lethongqi=object.children[0]; targetArr.forEach(d=>{ hongqi.position.set(d[0]*40-20,-50,d[1]*40-20) hongqi.scale.set(0.12,0.12,0.12) hongqi.material=newTHREE.MeshNormalMaterial({side:THREE.DoubleSide}); scene.add(hongqi.clone()) }) }) }
6.监听箱子的点击事件
每次点击的时候执行computeMove方法,判断如果是否可移动。
initEventListener(){ raycaster=newTHREE.Raycaster(); document.addEventListener('mousemove',function(event){ event.preventDefault(); mouse.x=(event.clientX/window.innerWidth)*2-1; mouse.y=-(event.clientY/window.innerHeight)*2+1; },false) document.addEventListener('click',()=>{ if(scene.children&&scene.getObjectByName('box')){ raycaster.setFromCamera(mouse,camera); letintersects=raycaster.intersectObjects(scene.getObjectByName('box_group').children); if(intersects[0]&&intersects[0].object.name=='box'){ this.computeMove(intersects[0].object,camera.position); } } }) }
7.监听游戏成功
如果成功了,那么简单的弹出提示。
isWinner(arr1,arr2){ letboo=true;//true为赢 arr1.forEach(d=>{ letres=arr2.some(dd=>{ returnd[0]==dd[0]&&d[1]==dd[1] }) if(!res){ boo=false; } }) if(boo){ setTimeout(()=>{ alert('恭喜你赢了!') },100) } }
由于当时做这个小案例时还是菜鸟,所以很少用一些three.js的辅助方法,见笑了。
以上就是如何使用three.js制作一个三维的推箱子游戏的详细内容,更多关于three.js制作推箱子游戏的资料请关注毛票票其它相关文章!