I am creating a simple breakout game. The ball should bounce when it collides with the platform. The top and bottom collisions work, but the left and right collisions don’t work.
I am creating a 2D game with a ball and a platform in JavaScript. The goal is to make the ball bounce off the platform when it collides. The top and bottom collisions work fine, but the left and right collisions fail. I’m using a simple function to check for intersecting rectangles.
Here are the key details:
- The ball moves at velocity velocityX and velocityY.
- Collisions are detected through the detectCollision function.
- For side collisions I added additional conditions (leftCollision and rightCollision), but they never trigger.
let board;
let boardWidth = 200;
let boardHeight = 200;
let context;
let playerWidth = 80;
let playerHeight = 10;
let playerVelocity = 10;
let player = {
x : boardWidth / 2 - playerWidth / 2,
y : boardHeight - playerHeight - 5,
width : playerWidth,
height : playerHeight,
velocity : playerVelocity
};
let ballWidth = 10;
let ballHeight = 10;
let ballVelocityX = -2;
let ballVelocityY = 1;
let ball = {
x : boardWidth / 2,
y : boardHeight / 2,
width : ballWidth,
height : ballHeight,
velocityX : ballVelocityX,
velocityY : ballVelocityY,
}
function outOfBounds(xPosition) {
return (xPosition < 0 || xPosition + player.width > boardWidth);
}
function playerMove(event) {
let mouseX = event.clientX - board.offsetLeft;
let nextPlayerX = mouseX - player.width / 2;
if (!outOfBounds(nextPlayerX)) {
player.x = nextPlayerX;
}
}
// Обнаружение колизии
function detectCollision(rectA, rectB) {
return (
rectA.x < rectB.x + rectB.width &&
rectA.x + rectA.width > rectB.x &&
rectA.y < rectB.y + rectB.height &&
rectA.y + rectA.height > rectB.y
);
}
function topCollision(ball, block) {
return detectCollision(ball, block) && (ball.y + ball.height) >= block.y;
}
function bottomCollision(ball, block) {
return detectCollision(ball, block) && ball.y <= (block.y + block.height);
}
function leftCollision(ball, block) {
return detectCollision(ball, block) && (ball.x + ball.width) >= block.x;
}
function rightCollision(ball, block) {
return detectCollision(ball, block) && ball.x <= (block.x + block.width);
}
function update() {
requestAnimationFrame(update);
context.clearRect(0, 0, boardWidth, boardHeight);
// игрок
context.fillStyle = "yellow";
context.fillRect(player.x, player.y, player.width, player.height);
// мяч
context.fillStyle = "white";
ball.x += ballVelocityX;
ball.y += ballVelocityY;
context.fillRect(ball.x, ball.y, ball.width, ball.height);
// отскок мяча
if (ball.y <= 0) {
ballVelocityY *= -1;
} else if (ball.x <= 0 || (ball.x + ball.width) >= boardWidth) {
ballVelocityX *= -1;
} else if (ball.y + ball.height >= boardHeight) {
// game over
}
if (topCollision(ball, player) || bottomCollision(ball, player)) {
ballVelocityY *= -1;
} else if (rightCollision(ball, player) || leftCollision(ball, player)) {
ballVelocityX *= -1;
}
}
// Функция отрисовки
window.onload = function () {
board = document.getElementById("game-canvas");
board.height = boardHeight;
board.width = boardWidth;
context = board.getContext("2d");
context.fillStyle = "yellow";
context.fillRect(player.x, player.y, player.width, player.height);
requestAnimationFrame(update);
document.addEventListener("mousemove", playerMove)
};
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #000;
color: #fff;
font-family: Arial, sans-serif;
overflow: hidden;
}
canvas {
border: 2px solid #fff;
background-color: #111;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script>
<title>breakout</title>
</head>
<body>
<canvas id="game-canvas"></canvas>
</body>
</html>
Problem:
The leftCollision and rightCollision collisions never work, even if the ball is clearly touching the sides of the platform.
The top and bottom collisions work without problems.