SidTheKid SidTheKid - 1 month ago 16
HTML Question

Ball collision not working

I'm working on a JQuery / JavaScript canvas brick break game, so I added the collision detection code if the ball hits the paddle or not, but when I ran the code, the collision detection code didn't work, I was wondering if anyone could help me? Here's the code.

JSFiddle: https://jsfiddle.net/18h7b9fd/

Main.js

$(document).ready(() => {
let fps = 60;
setInterval(init, 1000 / fps);

$(canvas).bind("mousemove", paddleControl);
})

// INIT
let init = () => {
draw(); //draw objects
animate(); //animate objects
collision(); //detect collision
}

// DRAW
let draw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
paddle.draw();
ball.draw();
}

// ANIMATE
let animate = () => {
ball.animate();
}

// COLLISION
let collision = () => {
ball.collision();
}

// CONTROL
let paddleControl = (e) => {
// get mouse pos
let rect = canvas.getBoundingClientRect();
let root = document.documentElement;
let mouseX = e.pageX - rect.left - root.scrollLeft;

paddle.x = mouseX - paddle.w / 2;
}


Objects.js

class Paddle {
constructor(x, y, w, h, color) {
this.x = canvas.width / 2 - 100 / 2;
this.y = canvas.height - 60;
this.w = 100;
this.h = 10;
this.color = "#fff";
}

draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
}

class Ball {
constructor(x, y, r, color, speedX, speedY) {
this.x = canvas.width / 2 - 10 / 2;
this.y = canvas.height / 2 - 10 / 2;
this.r = 10;
this.color = "#fff";
this.speedX = 6;
this.speedY = 6;
}

draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}

animate() {
this.x += this.speedX;
this.y += this.speedY;
}

collision() {
// BALL TO PADDLE
let paddleTop = paddle.y - paddle.h;
let paddleBottom = canvas.height - paddleTop;
let paddleLeft = paddle.x;
let paddleRight = paddle.x + paddle.w;

if(this.y >= paddleTop && this.y <= paddleBottom &&
this.x >= paddleLeft && this.x <= paddleRight) {
this.speedY *= -1;
}

// BALL TO WALL
if(this.x >= canvas.width) this.speedX *= -1; //left
if(this.x <= 0) this.speedX *= -1; //right

if(this.y >= canvas.height) this.reset(); //bottom
if(this.y <= 0) this.speedY *= -1; //top
}

reset() {
this.x = canvas.width / 2 - this.r / 2;
this.y = canvas.height / 2 - this.r / 2;
this.animate();
}
}

let paddle = new Paddle(this.x, this.y, this.w, this.h, this.color);
let ball = new Ball(this.x, this.y, this.r, this.color, this.speedX, this.speedY);
console.log(paddle);
console.log(ball);

Answer

The problem is the way you are setting the paddle top and bottom. Use this instead:

let paddleTop = paddle.y;
let paddleBottom = paddleTop + paddle.h;

Currently the way you are setting the values makes it impossible for the condition to ever be true (as paddle bottom is always less than paddle top).

I have put together a fiddle here: https://jsfiddle.net/gegbqv5p/

You will also notice that I didn't use jQuery. For what you have so far, it really isn't necessary.