本文介绍第一回中主要功能的具体实现

坦克类

坦克实例对象初始化时,会绘制自身躯体,由三部分组成:坦克底座(Path.Rectangle)、炮塔(Path.Circle)及炮管(Path),具体代码如下:

init() {
  this.path = new paper.Group({
    children: [
      // 炮身
      new paper.Path.Rectangle({
        name: 'base',
        center: this.position,
        size: new paper.Size(SIZE),
        strokeColor: this.color
      }),
      // 炮管
      new paper.Path({
        name: 'turret',
        segments: [this.position, this.position.add(this.direction)],
        strokeWidth: 5,
        strokeColor: this.color,
        strokeCap: 'round'
      }),
      // 炮塔
      new paper.Path.Circle({
        radius: SIZE / 4,
        center: this.position,
        fillColor: this.color
      })
    ]
  })
}
  • 坦克底座: 由position确定,尺寸由Size确定。
  • 炮塔:由position确定,尺寸由Size确定。
  • 炮管: 由position确定,长度由direction确定。

NPC运动逻辑

autoRun(position) {
  this.direction = position.subtract(this.path.position).clone()
  this.updateTurret()
}
updateTurret() {
  const vector = this.direction.normalize(50).clone()
  const vector_end = this.path.children['base'].position.add(vector).clone()
  const turret = this.path.children['turret']
  turret.replaceWith(new paper.Path(
    {
      name: 'turret',
      segments: [this.path.children['base'].position, vector_end],
      strokeWidth: 5,
      strokeColor: this.color,
      strokeCap: 'round'
    }
  ))
  this.path.position = this.path.position.add(this.direction.normalize()).clone()
}

每帧调用autoRun函数,更新炮塔,更新位置

Role的运动逻辑

键盘获取按键值,确定移动方向变动position,鼠标移动更新炮塔位置。

// 根据方向命令改变tank位置
handleChangePosition(e, width, height) {
  let newP = null
  if (e.key === 'left' || e.key === 'a') {
    newP = new paper.Point(this.path.position.x - this.step, this.path.position.y)
  } else if (e.key === 'right' || e.key === 'd') {
    newP = new paper.Point(this.path.position.x + this.step, this.path.position.y)
  } else if (e.key === 'up' || e.key === 'w') {
    newP = new paper.Point(this.path.position.x, this.path.position.y - this.step)
  } else if (e.key === 'down' || e.key === 's') {
    newP = new paper.Point(this.path.position.x, this.path.position.y + this.step)
  }
  if (!this.judeBoundary(newP, width, height)) {
    this.path.position = newP
    this.position = this.path.position
  }
  newP = null
}

Role开火的逻辑

获取空格键值,创建一个Ammunition类的实例,在炮管顶端处生成炮弹,并每帧更新炮弹位置

fire() {
  const ammunition = new Ammunition(this.position, 'circle', 5, 'orange')
  this.AmmunitionDepo.push(ammunition)
}