I created a game based on Mozilla Developer's breakout game, but at a certain moment when the ball collides with the paddle, it zig zags inside it and comes out. How can I solve this problem? Here is my javascript code:
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const ballRadius = 10;
const paddleHeight = 10;
const paddleWidth = 75;
let paddleX = (canvas.width - paddleWidth) / 2;
let rightPressed = false;
let leftPressed = false;
let x = canvas.width / 2;
let y = canvas.height - 30;
let dx = 2;
let dy = -2;
let paddleY = canvas.height - paddleHeight;
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
drawBall();
drawPaddle();
// Colisão da bola no eixo X
if (x + dx < 0 + ballRadius || x + dx > canvas.width - ballRadius) {
dx = -dx
}
// Colisão eixo Y
if (y + dy < 0 + ballRadius) {
dy = -dy
}
if (x + dx > canvas.width - ballRadius || x + dx < ballRadius) {
dx = -dx
}
if (y + dy < ballRadius) {
dy = -dy
} else if (y + dy > canvas.height - (ballRadius * 2)) {
if (x > paddleX && x < paddleX + paddleWidth) {
dy = -dy
} else if (y + ballRadius > canvas.height) {
alert("a")
document.location.reload();
clearInterval(interval)
}
}
if (rightPressed) {
paddleX += 7;
if (paddleX + paddleWidth > canvas.width) {
paddleX = canvas.width - paddleWidth
}
} else if (leftPressed) {
paddleX -= 7
if (paddleX < 0) {
paddleX = 0
}
}
x += dx;
y += dy;
}
// Eventos de controle via teclado
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.key === "Right" || e.key === "ArrowRight") {
rightPressed = true;
} else if (e.key === "Left" || e.key === "ArrowLeft") {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.key === "Right" || e.key === "ArrowRight") {
rightPressed = false;
} else if (e.key === "Left" || e.key === "ArrowLeft") {
leftPressed = false;
}
}
const interval = setInterval(draw, 10);
This is a gif with the problem:

I try different solutions but not resolve my error.
This happens when the ball hits the user's paddle first at the side, so that it is already well below the top of the paddle when it first hits it. When the vertical direction is flipped, the next iteration is not enough to bring the ball above the paddle -- it is still below its top. And the problem occurs: the vertical direction is flipped again!
I sized the canvas so that it occurs immediately on the first bounce (provided the user does not move the paddle):
The fix is straightforward: don't flip the vertical direction
dy, but force it to be negative, like this:If it already was negative, then it wont be flipped again.
Here is the same code as above, but with the fix applied: