Skip to content
On this page

Setp4:碰撞判断

在步骤 3 中,我们没有处理碰撞的问题。有了步骤 3 之后,简单的思路可以这样做: 在真正移动前,先在内存里模拟一次移动过程(不直接操作 position 和 board 的值),然后判断此过程中有无碰撞。

碰撞本身的逻辑判断是很明确的:

1、移动后方块是否到达左、右、下边界。

在步骤 3 中移动方块代码如下:

js
board.value[position.value.y + i][position.value.x + j] = block.value[i][j]

因此现在要添加的判断代码如下:

  • 左边界:position.value.x + j < 0
  • 右边界:position.value.x + j >= 10
  • 下边界:position.value.y + i >= 20

2、移动后,新位置上是否有其他方块。

这里只用检查board[position.value.y + i][position.value.x + j]是否已经等于 1。

Have a try

下面的演示中添加了方法canMove,你可以试试动手完善它。

点击查看样例代码
js
function canMove(nextMove) {
  msg.value = ''
  const nextPosition = { ...position.value }
  // deep clone
  const nextBoard = JSON.parse(JSON.stringify(board.value))

  // 擦除
  for (let i = 0; i < block.value.length; i++) {
    for (let j = 0; j < block.value[i].length; j++) {
      if (block.value[i][j]) {
        nextBoard[nextPosition.y + i][nextPosition.x + j] = 0
      }
    }
  }

  switch (nextMove) {
    case 'down':
      nextPosition.y++
      break
    case 'right':
      nextPosition.x++
      break
    case 'left':
      nextPosition.x--
      break
  }

  for (let i = 0; i < block.value.length; i++) {
    for (let j = 0; j < block.value[i].length; j++) {
      if (block.value[i][j]) {
        // 边界判断
        if (
          nextPosition.y + i >= 20 ||
          nextPosition.x + j >= 10 ||
          nextPosition.x + j < 0
        ) {
          msg.value = '碰到边界'
          return false
        }

        // 碰撞判断
        if (nextBoard[nextPosition.y + i][nextPosition.x + j]) {
          msg.value = '碰到其他方块'
          return false
        }
      }
    }
  }

  return true
}

TIP

样例代码很容易理解,但有很多可以优化的地方。