如何使用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制作推箱子游戏的资料请关注毛票票其它相关文章!