简体   繁体   中英

Bouncing ball braking bricks game, fails to bounce of a brick

So my problem is that the ball just passes trough the bricks, nothing happens. I will put the whole code in jsbin, here I post only the piece that is not working. As you can see, I got a bouncing ball, a racket, bricks and an animationFrame function.

for (var i in bricks) {
    if (!bricks[i].isDestroyed) {

        if (
            (this.y + this.radius == bricks[i].y - bricks[i].height)
            && (this.x >= bricks[i].x)
            && (this.x <= bricks[i].x + bricks[i].width)
        ) {
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.y = "up";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
        }

        if (
            (this.y - this.radius == bricks[i].y)
            && (this.x >= bricks[i].x)
            && (this.x <= bricks[i].x + bricks[i].width)
        ) {
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.y = "down";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
        }

        if (
            (this.x - this.radius == bricks[i].x)
            && (this.y - this.radius <= bricks[i].y)
            && (this.y - this.radius >= bricks[i].y - bricks[i].height)
        ) { 
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.x = "left";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
        }

        if (
            (this.x == bricks[i].x + bricks[i].width)
            && (this.y - this.radius <= bricks[i].y)
            && (this.y - this.radius >= bricks[i].y - bricks[i].height)
        ) {
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.x = "right";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
        }
    }
}

Jsbin code: http://jsbin.com/eZOxusaQ/1/watch?html,js,output

It looks like the collision code is using == on some of the checks when you probably want an inequality. So my guess is the ball is stepping over that exact position, resulting in the other checks being skipped. Switch all comparisons to be >= or <= as appropriate and see if that fixes it.

Fixed your code.

Basically, I changed the == to <= , as the ball will never hit this EXACT spot. Furthermore I added a break inside each of the if -conditions to quit the check when one brick got hit, as you want the ball to jump off and not to exterminate a whole row.

for (var i in bricks) {
    if (!bricks[i].isDestroyed) {                   
        if ((this.y + this.radius <= bricks[i].y - bricks[i].height) && (this.x >= bricks[i].x) && (this.x <= bricks[i].x + bricks[i].width)) {
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.y = "up";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
            break;
        }
        if ((this.y - this.radius <= bricks[i].y) && (this.x >= bricks[i].x) && (this.x <= bricks[i].x + bricks[i].width)) {
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.y = "down";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
            break;
        }
        if ((this.x - this.radius <= bricks[i].x) && (this.y - this.radius <= bricks[i].y) && (this.y - this.radius >= bricks[i].y - bricks[i].height)) {                       
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.x = "left";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
            break;
        }
        if ((this.x <= bricks[i].x + bricks[i].width) && (this.y - this.radius <= bricks[i].y) && (this.y - this.radius >= bricks[i].y - bricks[i].height)) {                       
            bricks[i].isDestroyed = true;
            destroyedBrick = true;
            this.direction.x = "right";
            ctx.clearRect(bricks[i].x, bricks[i].y, bricks[i].width, bricks[i].height);
            break;
        }                  
    }
}

EDIT
You will get a problem when your ball hits an "inner brick", for example a brick one row above a row with still bricks left. As your ball will exterminate these bricks with your current conditions, as the coordinates of the ball will be smaller than the coordinates of your brick. But that's more a general problem of your logic. You'll need to include more checks for this one. ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM