Reputation: 309
i have a logic problem that maybe you smart guys can help me to resolve. I am learning Javascript with Canvas and i'm trying to build a sort of "brakeout" game using pure Javascript.
http://www.seas.upenn.edu/~cis120e/hw/SwingGame/images/breakout.png
I created the paddle, the ball, and then an array of blocks-Objects with different properties(xPos, yPos, width...etc), now i am trying to detect the collision of the ball with the blocks on the top of the screen.
This is the way i do:
//This is my block Object definition
function block(x,y,width,height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
ctxBlock.fillStyle = 'green';
ctxBlock.fillRect(this.x, this.y, this.width, this.height);
}
//This is for draw blocks on the canvas
mattone.prototype.draw = function(){
ctxBlock.fillStyle = 'green';
ctxBlock.fillRect(this.x, this.y, this.width, this.height);
}
//This is the check for collision method
var blocks = [];
function checkCollision(){
for (var i = 0; i < blocks.length; i++){
if(ballY - ballRadius <= blocks[i].y + blockWidth){
ctxBlocks.clearRect(tmpx, tmpy, blockWidth, blockHeight);
speedY = (-speedY);
break;
}
}
checkColl = requestAnimationFrame(checkCollision);
}
Basically i am trying to tell the canvas that when the "Y" of the ball is "<" then the "Y" of one of the block in the array of blocks(looping trough and checking for every single block), he must delete that block and bounce down.
But what it does is always cancel the first block on the left in that line of blocks, and not the block he touch.
This should be the link to my code link *Plese note i used the word mattoni instead of block in my code
Have a nice day to you all
Upvotes: 1
Views: 2124
Reputation: 1092
Very nice! Thank you for providing a complete jsfiddle, too. I've made an update to that:
http://jsfiddle.net/43mwc/2/ . Now for an explanation: your collision check simply needs to check all bounds of each block, not just the bottom as you're doing. So I changed this:
if(ballY - ballRadius <= blocks[i].y + blockWidth){
to this (with your jsfiddle's wording):
if(ballY-ballRadius <= mattoni[i].y + 10- padding && (ballX - ballRadius) >= mattoni[i].x && (ballX + ballRadius) <= (mattoni[i].x + mattWidth)){
To explain, your code looped through every brick checking if the ball was directly below each brick. The whole bottom row of bricks satisfies that criterion, so your loop broke (as in break;
) on the first brick in the loop which lay on the bottom row. Now the ball's position along the x axis is being checked to be between each brick's left and right edges. There's still one scenario that's not covered here: bricks being hit from the top. I'll leave that one to you.
Upvotes: 1
Reputation: 154838
You only checked for the y value in the collision check and not the x value. Whenever you hit a brick on the last row, the leftmost brick got cleared because it matched the y value. After that, you break out of the loop.
Second, you did not keep track of which block has already been cleared. As a result, it is that left brick on the last row that was cleared each loop, and other bricks didn't get a change to get cleared, because you break out of the loop after that one.
Upvotes: 1