Canvas中小球与Paddle的碰撞检测实现方法咨询
完善小球与Paddle的碰撞检测逻辑
你之前的代码只判断了x轴位置,没有验证y轴方向上小球与paddle的重叠区域,导致碰撞判断失效。以下是修正后的完整逻辑:
假设小球为圆形(基于中心坐标+半径)
先确保已定义常量 PADDLE_WIDTH、PADDLE_HEIGHT、BALL_RADIUS:
function checkCollision() { // 检测左侧Paddle碰撞 if (ball.leftorright === 0) { // 小球向左移动时才检测左侧碰撞 const ballLeftEdge = ball.x - BALL_RADIUS; const ballRightEdge = ball.x + BALL_RADIUS; const ballTopEdge = ball.y - BALL_RADIUS; const ballBottomEdge = ball.y + BALL_RADIUS; const paddle1RightEdge = PADDLE_WIDTH; const paddle1TopEdge = paddle1.y; const paddle1BottomEdge = paddle1.y + PADDLE_HEIGHT; // 小球右边缘碰到Paddle左边缘,且y轴范围重叠 if (ballRightEdge >= 0 && ballLeftEdge <= paddle1RightEdge && ballBottomEdge >= paddle1TopEdge && ballTopEdge <= paddle1BottomEdge) { ball.leftorright = 1; // 反转方向向右 } } // 检测右侧Paddle碰撞 if (ball.leftorright === 1) { // 小球向右移动时才检测右侧碰撞 const ballLeftEdge = ball.x - BALL_RADIUS; const ballRightEdge = ball.x + BALL_RADIUS; const ballTopEdge = ball.y - BALL_RADIUS; const ballBottomEdge = ball.y + BALL_RADIUS; const paddle2LeftEdge = canvas.width - PADDLE_WIDTH; const paddle2TopEdge = paddle2.y; const paddle2BottomEdge = paddle2.y + PADDLE_HEIGHT; // 小球左边缘碰到Paddle右边缘,且y轴范围重叠 if (ballLeftEdge <= canvas.width && ballRightEdge >= paddle2LeftEdge && ballBottomEdge >= paddle2TopEdge && ballTopEdge <= paddle2BottomEdge) { ball.leftorright = 0; // 反转方向向左 } } }
假设小球为矩形(基于左上角坐标+宽高)
如果小球是矩形,定义常量 BALL_WIDTH、BALL_HEIGHT,代码调整为:
function checkCollision() { // 左侧Paddle碰撞检测 if (ball.leftorright === 0) { const ballRightEdge = ball.x + BALL_WIDTH; const ballBottomEdge = ball.y + BALL_HEIGHT; const paddle1RightEdge = PADDLE_WIDTH; const paddle1BottomEdge = paddle1.y + PADDLE_HEIGHT; if (ballRightEdge >= 0 && ball.x <= paddle1RightEdge && ballBottomEdge >= paddle1.y && ball.y <= paddle1BottomEdge) { ball.leftorright = 1; } } // 右侧Paddle碰撞检测 if (ball.leftorright === 1) { const ballLeftEdge = ball.x; const ballBottomEdge = ball.y + BALL_HEIGHT; const paddle2LeftEdge = canvas.width - PADDLE_WIDTH; const paddle2BottomEdge = paddle2.y + PADDLE_HEIGHT; if (ballLeftEdge <= canvas.width && (ball.x + BALL_WIDTH) >= paddle2LeftEdge && ballBottomEdge >= paddle2.y && ball.y <= paddle2BottomEdge) { ball.leftorright = 0; } } }
核心逻辑说明
- 先判断小球移动方向,避免同一帧内重复触发碰撞反转
- 同时验证x轴重叠和y轴重叠两个条件,只有两者都满足时才判定为碰撞
- 边界判断时加入了画布边缘的校验,防止小球超出画布后误触发碰撞
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

