You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:10:27