Appearance
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
样例代码很容易理解,但有很多可以优化的地方。