Search code examples
javascriptgame-physicsphysics

Javascript: Ball hitting rectangle Y Axis Response


I am making a pong game with javascript and have trouble creating a realistic, Y axis reaction when the ball is hitting the paddle.

Currently I have a directional velocity of dx and dy, and my current code just inverts the direction of dy. The problem with this is that, the ball will just keep bouncing back and forth, at the same direction, regardless of where it gets hit on the paddle.

I would like to create a realistic approach, where depending on where it gets hit on the paddle, that determines the direction of the ball. So if it gets hit right at the center, then itll just bounce back to the same direction it came from, however if it got hit near the top edge, it'll bounce down etc.

I am having trouble finding out where to start with this approach, can someone just guide me in the right direction?


Solution

  • Imagine you calculate the distance between the center of the paddle and the point where the ball hit and call it d. Let's suppose d has a positive value when the ball hit above the center of the paddle. You can now add d * -0.1 to the Y velocity of your ball and it will start changing direction. Now just adjust the parameters and tell me if it works!

    var canvas = document.querySelector('canvas');
    var resize = function () {
      canvas.width = innerWidth;
      canvas.height = innerHeight;
    };
    resize();
    var ctx = canvas.getContext('2d');
    var ball = {
      size: 3,
      x: 1,
      y: canvas.height/2,
      vx: 2,
      vy: 0
    };
    var paddle = {
      height: 40,
      width: 3,
      x: canvas.width/2,
      y: canvas.height/2
    };
    addEventListener('mousemove', function (e) {
      paddle.y = e.clientY - (paddle.height/2);
    });
    var loop = function () {
      resize();
      ball.x += ball.vx;
      ball.y += ball.vy;
      if (ball.x > canvas.width || ball.x < 0) ball.vx *= -1; // horiz wall hit
      if (ball.y > canvas.height || ball.y < 0) ball.vy *= -1; // vert wall hit
      if (ball.x >= paddle.x && ball.x <= paddle.x + paddle.width && ball.y >= paddle.y && ball.y <= paddle.y + paddle.height) {
        // paddle hit
        var paddleCenter = paddle.y + (paddle.height/2);
        var d = paddleCenter - ball.y;
        ball.vy += d * -0.1; // here's the trick
        ball.vx *= -1;
      }
      ctx.fillRect(ball.x,ball.y,ball.size,ball.size);
      ctx.fillRect(paddle.x,paddle.y,paddle.width,paddle.height);
      requestAnimationFrame(loop);
    };
    loop();
    body {overflow: hidden; margin: 0}
    canvas {width: 100vw; height: 100vh}
    <canvas></canvas>