3D堆叠游戏——第四步 结束判定,记分器等

747 阅读3分钟

上一篇写的是裁切主角分为有效区域和无效区域

有效区域作为底板放置在场景内,无效区域做自由落体下落并删除

镜头跟进

在每放置一块主角的时候镜头随之向上移动

  moveCamera(){
    // 定义控制器target的y值
    const oldty = this.controls.target.y
    const newty = oldty + 1 // 每一次向上移动1
    console.log(oldty, newty)
    let tween:any = NumberAnimate(oldty, newty, 100)
    tween.onUpdate(()=>{
      this.controls.target.setY(tween._object.p)
    })
  }

游戏结束判定

判定游戏结束 首先判定底板和主角没有交集,就是裁切的有效区域的顶点信息为空

intersectResult.geometry.vertices.length > 0

另一种情况是未操作空格进行放置 就是主角运动结束而没有点击的情况

判定游戏结束后,将镜头拉至全景

将场景下所有内容展现出来

记分环节

记分可以按照堆叠高度计算 也可以按照堆叠数量计算 可以按照剩余总面积计算

咱们搞个高难度的,按照搭建表面积计算

每次叠加的有效区域表面积相加得出记分结果

通过box3得到有效区域的尺寸,再将每个有效区域记录在页面

计算有效区域的方法之前封装过getsize,继续使用这个再次封装一个getarea

export function getArea(mesh):number {
  const size = new THREE.Vector3()
  getSize(mesh, size)
  const area = Math.floor(size.x * size.z)
  return area
}

页面上需要一个dom节点用来呈现分数

fractionDom:HTMLElement = document.querySelector('#fraction')

给dom节点赋值

 upDateFraction(){
    this.fractionDom.innerText = this.areaCount + ''
  }

制作开始按钮

开始按钮功能

const mark: HTMLElement = document.querySelector('#mark')
const startBtn: HTMLElement = document.querySelector('#start-game')
console.log(mark, startBtn)
if (mark && startBtn) {
  console.log(startBtn)
  startBtn.onclick = function () {
    mark.style.display = 'none'
    // 缩放镜头
    createGame.restart()
  }
}

restart 功能 将变量重置之后,拉近镜头,调整视角,重新绘制主角

restart() {
  if (this.isOver) {
    this.floorGroup.remove(...this.floorGroup.children)
    this.leadCount = 0
    this.leadCube = null
    this.tween = null
    this.T = 2000
    this.flag = false
    this.isOver = false // 是否游戏结束
    this.areaCount = 0  // 分数
    this.upDateFraction()
    this.scene.updateMatrix()
    this.initFloor()
  }
  this.undateCameraZoom(5.5, () => {
    // 开始创建第一个主角
    this.createlead()
  })
}

结束

游戏开发到次就差不多完事了,剩下的就是一些代码的规范了

ts中尽量不要出现any这种类型规范

以接口为例

interface Element {
  scene: THREE.Object3D
  camera: THREE.OrthographicCamera
  controls: OrbitControls
}

constructor(element: Element) {
  this.scene = element.scene
  this.camera = element.camera
  this.controls = element.controls
  this.floorGroup = new THREE.Group()
  this.scene.add(this.floorGroup)
  this.initFloor()
  window.addEventListener('keydown', this.leadStop.bind(this))
}

如果要规定一个three元素类型 比如scene 场景,就可以在官网上看scene的基类是哪个

它的基类是object3d 所以可以用THREE.Object3D对它进行约束

如果你使用的方法在基类中没有 比如scene的autoUpdate这个方法是在自己本身的

那么就需要将值规范为 THREE.Scene

scene: THREE.Scene

然后就不报错啦

也可以直接写本身,看需求呗

其实可以兼容一下移动端,毕竟手游目前比较受欢迎啊

猛戳这里体验

欢迎童鞋们在评论区打出自己的分数

3D堆叠游戏——第一步 基础 初始化游戏

3D堆叠游戏——第二步 控制 控制主角移动以及停止

3D堆叠游戏——第三步 切割等功能

代码

跨年啦,祝大家新年快乐

准备放纵一下,上完今天的班,今年就不工作了

2021 犇向美好