小船碰撞检测源码

190 阅读1分钟

import $ from 'jquery'

// 小船对应泊位的下标

class Boat { constructor(img, ctx,ind) {

// 状态 0:停止 ,1 :行驶
this._state = 1
// 小船到泊位的下标
this.nearBoatLeft = [0,0,-(45/1920*window.innerWidth),350/1920*window.innerWidth,670/1920*window.innerWidth]
this.leftPlaceIndex = ind
this.nearBoatTop= [430/877*(window.innerHeight-60),250/877*(window.innerHeight - 60),0,0,0]
// canvas 画图
this.ctx = ctx
// 图片的位置
this.pop = {
  left: this.nearBoatLeft[this.leftPlaceIndex],
  top: this.nearBoatTop[this.leftPlaceIndex],
  width: document.querySelector(img).style.width,
}
this.imgEle = img
// 图片缩放
this.zoom = this.leftPlaceIndex===0?2.5:this.leftPlaceIndex===1?1.5:0.9
this.direction = 1
// 方向
this.vy = 0.5
this.vx = 0.8
// 底部
;(this.parent = [
  document.querySelector('.berth1'),
  document.querySelector('.berth2'),
  document.querySelector('.berth3'),
  document.querySelector('.berth4'),
  document.querySelector('.berth5'),
]),
  // 警告样式
  (this.colorList = [
    { color: ['#22454C', '#686C3A'] },
    { color: ['#5E623A', '#8E7F34'] },
  ])
  // 警告定时器
this.timerOfHint = null
// 靠近的停泊位
this.nearPart = null

}

船移动

move(diff) {

// 解析参数
const { _state, vy, vx, pop, imgEle } = this
//  判断元素状态
if (_state) {
  // 更改元素位置
  this.zoom += 0.0025 * this.direction
  pop.left += (vx + diff) * this.direction
  pop.top += (vy + diff) * this.direction
  // 设置元素位置
  document.querySelector(imgEle).style.left = pop.left + 'px'
  // document.querySelector(imgEle).style.left =
  //   ocument.querySelector(imgEle).offset + 'px'

  document.querySelector(imgEle).style.top = pop.top + 'px'
  document.querySelector(imgEle).style.width = this.zoom + '%'
  
  // 循环判断元素底部碰撞检测
  for (let i = 0; i < this.parent.length; i++) {
    const { offsetTop, offsetLeft } = this.parent[i]
    // 边界处理
    if (pop.top < -30 || pop.left < -105 || pop.left > window.innerWidth) {
      this._state = 0
      setTimeout(() => {
        // console.log('Y:----', this.nearBoatLeft[this.leftPlaceIndex])
        this._state = 1
        this.pop.left = this.nearBoatLeft[this.leftPlaceIndex]
        this.pop.top =  this.nearBoatTop[this.leftPlaceIndex],
        this.vx = 0.8
        this.vy = 0.5
        this.zoom = this.leftPlaceIndex === 0 ?2.5: this.leftPlaceIndex === 1 ? 1.5 : 0.8

        this.direction = -this.direction
      }, 9000)
      return
    }

    // 帆船顶部到父级的距离+空隙+帆船自己的高度
    if (
      pop.top  + document.querySelector(imgEle).offsetHeight/1.5 >
      offsetTop &&
      pop.left + 20 > offsetLeft
    ) {
        this.nearPart = i + 1

        // 判断当前泊位上是否有停靠的船只
        let ship = $('.berth' + this.nearPart + ' .shipPosition').find(
          'img'
        )[0]
        if (
          ship &&
          ship.offsetTop + 1 >= ship.parentElement.offsetHeight * 0.1
        ) {
          this.draw()
          this.changeColor()
        }
        // console.log(this.nearBoatTop)
        // console.log(pop.top)
        this._state = 0
        // 停靠
        setTimeout(() => {
          this.nearPart = i + 1
          i = 0
          //  退出
          this._state = 1
          window.clearInterval(this.timerOfHint)
          this.ctx.clearRect(0, 0, window.innerHeight, window.innerWidth)
          this.vx = 0.8
          this.direction = -this.direction
        }, 3000)
        return
      }
    
  }

}

} // 画靠近样式 draw() { const { pop, ctx, imgEle } = this

document.querySelector('#canvas').style.left = pop.left - 55 + 'px'
document.querySelector('#canvas').style.top =pop.top-15 + 'px'

ctx.globalAlpha = 0.5
ctx.ellipse(85, 55, 75, 35, 0, 0, Math.PI * 2)
ctx.fillStyle = this.colorList[0].color[0]
ctx.strokeStyle = this.colorList[0].color[1]
ctx.setLineDash([3, 5])
ctx.fill()
ctx.stroke()

ctx.beginPath()
ctx.globalAlpha = 0.7
ctx.ellipse(85, 55, 59, 29, 0, 0, Math.PI * 2)
ctx.fillStyle = this.colorList[1].color[0]
ctx.strokeStyle = this.colorList[1].color[1]
ctx.setLineDash([3, 5])
ctx.fill()
ctx.stroke()

ctx.beginPath()
ctx.globalAlpha = 0.5
ctx.ellipse(85,55, 40, 18, 0, 0, Math.PI * 2)
ctx.fillStyle = '#C0AC24'
ctx.strokeStyle = '#9A8831'
ctx.setLineDash([3, 5])
ctx.fill()
ctx.stroke()

}

做涟漪样式

changeColor() {

const { colorList, ctx } = this
this.timerOfHint = setInterval(() => {
  colorList.push(colorList[0])
  colorList.shift()
  ctx.clearRect(0, 0, window.innerHeight, window.innerWidth)
  this.draw()
}, 300)

} }

export default Boat