欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何使用three.js 制作一個(gè)三維的推箱子游戲

 更新時(shí)間:2020年07月29日 10:28:09   作者:郭先生  
這篇文章主要介紹了如何使用three.js 制作一個(gè)三維的推箱子游戲,文中代碼非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

今天郭先生發(fā)現(xiàn)大家更喜歡看我發(fā)的three.js小作品,今天我就發(fā)一個(gè)3d版本推箱子的游戲,其實(shí)webGL有很多框架,three.js并不合適做游戲引擎,但是可以嘗試一些小游戲。在線案例請(qǐng)點(diǎn)擊

要制作一個(gè)推箱子游戲,正常要有以下4個(gè)步驟

  1. 定義一些數(shù)組,要有開(kāi)始箱子數(shù)組、結(jié)束箱子數(shù)組、地面數(shù)組還有墻面數(shù)組,有這四個(gè)數(shù)組就可以組成一個(gè)關(guān)卡。
  2. 根據(jù)數(shù)組初始化地面墻面箱子和目標(biāo)地點(diǎn)標(biāo)志物。
  3. 使用FirstPersonControls控制器,控制相機(jī)移動(dòng),根據(jù)地面箱子和墻面算出可移動(dòng)區(qū)域。
  4. 根據(jù)相機(jī)正對(duì)箱子時(shí),用鼠標(biāo)點(diǎn)擊箱子,控制箱子移動(dòng),并做成功性校驗(yàn)。

下面我們上代碼分析代碼

1. 定義數(shù)組

這四個(gè)數(shù)組分別是墻的數(shù)組、地面的數(shù)組、箱子初始位置數(shù)組和目標(biāo)數(shù)組。

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. 根據(jù)箱子初始位置數(shù)組初始化箱子

initBox() {
  var textureBox = new THREE.TextureLoader().load("/static/images/base/crate.png");
  if (boxGroup) {
    scene.remove(boxGroup)
  }
  boxGroup = new THREE.Group();
  boxGroup.name = 'box_group'
  boxArr.forEach(d => {
    var boxGeom = new THREE.BoxGeometry(40, 40, 40);
    var boxMate = [];
    boxGeom.faces.forEach(d => boxMate.push(new THREE.MeshBasicMaterial({ map: textureBox })))
    var boxMesh = new THREE.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. 根據(jù)地面數(shù)組初始化地面

initGround() {
  var textureGround = new THREE.TextureLoader().load("/static/images/wall/plaster.jpg", () => {this.loaded_num --});
  var textureGroundNormal = new THREE.TextureLoader().load("/static/images/wall/plaster-normal.jpg", () => {this.loaded_num --});
  var textureGroundSpecular = new THREE.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);
  var materialGround = new THREE.MeshPhongMaterial({
    map: textureGround
  })
  materialGround.normalMap = textureGroundNormal;
  materialGround.specularMap = textureGroundSpecular;
  var ground = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000, 1, 1), materialGround);
  ground.rotation.x = - Math.PI / 2;
  scene.add(ground);
}

4. 根據(jù)墻數(shù)組初始化地面

initWall() {
  var normal = new THREE.TextureLoader().load("/static/images/wall/stone.jpg", () => {this.loaded_num --});
  var bump = new THREE.TextureLoader().load("/static/images/wall/stone-bump.jpg", () => {this.loaded_num --});
  wallArr.forEach(d => {
    var wallBox = new THREE.BoxGeometry(40, 40, 40);
    var material = new THREE.MeshPhongMaterial({
      map: normal,
      bumpMap: bump,
      bumpScale: 1
    })
    var wall = new THREE.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. 根據(jù)目標(biāo)數(shù)組初始化目標(biāo)物

initTarget() {
  let objLoader = new OBJLoader();
  objLoader.setPath("/static/images/texture/hongqi/");
  objLoader.load('hongqi.obj', (object) => {
    this.loaded_num --;
    let hongqi = 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 = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide });
      scene.add(hongqi.clone())
    })
  })
}

6. 監(jiān)聽(tīng)箱子的點(diǎn)擊事件

每次點(diǎn)擊的時(shí)候執(zhí)行computeMove方法,判斷如果是否可移動(dòng)。

initEventListener() {
  raycaster = new THREE.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);
      let intersects = raycaster.intersectObjects(scene.getObjectByName('box_group').children);
      if (intersects[0] && intersects[0].object.name == 'box') {
        this.computeMove(intersects[0].object, camera.position);
      }
    }
  })
}

7. 監(jiān)聽(tīng)游戲成功

如果成功了,那么簡(jiǎn)單的彈出提示。

isWinner(arr1, arr2) {
  let boo = true; //true為贏
  arr1.forEach(d => {
    let res = arr2.some(dd => {
      return d[0] == dd[0] && d[1] == dd[1]
    })
    if(!res) {
      boo = false;
    }
  })
  if(boo) {
    setTimeout(() => {
      alert('恭喜你贏了!')
    },100)
  }
}

由于當(dāng)時(shí)做這個(gè)小案例時(shí)還是菜鳥(niǎo),所以很少用一些three.js的輔助方法,見(jiàn)笑了。

以上就是如何使用three.js 制作一個(gè)三維的推箱子游戲的詳細(xì)內(nèi)容,更多關(guān)于three.js 制作推箱子游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論