Breakout collision problem?

Started by
4 comments, last by stein102 11 years ago

This is my code for the ball colliding with the paddle in my game. As of right now, if the ball approaches the paddle and hits it on the corner, the ball seems to get trapped inside of the paddle. Any suggestions?

I'm using the Slick2d API if it makes a difference.


		if (ball.ballCircle.intersects(paddle.paddleRect)) {
			//left
			if(ball.ballCircle.getMaxX() <= paddle.paddleRect.getMinX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMinX()-ball.ballCircle.getRadius()-1);
				ball.setDx(-ball.getDx());
			}
			//Right
			if( ball.ballCircle.getMinX() >= paddle.paddleRect.getMaxX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()+1);
				ball.setDx(-ball.getDx());
			}
			//Top
			if(ball.ballCircle.getMaxY() <= paddle.paddleRect.getMinY()){
				ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-1);
				ball.setDy(-ball.getDy());
			}	
		}
Advertisement


		if (ball.ballCircle.intersects(paddle.paddleRect)) {
			//left
			if(ball.ballCircle.getMaxX() <= paddle.paddleRect.getMinX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMinX()-ball.ballCircle.getRadius()-1);
				ball.setDx(-ball.getDx());
			}
			//Right
			if( ball.ballCircle.getMinX() >= paddle.paddleRect.getMaxX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()+1);
				ball.setDx(-ball.getDx());
			}
			//Top
			if(ball.balllCircle.getMaxY() <= paddle.paddleRect.getMinY()){
				ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-1);
				ball.setDy(-ball.getDy());
			}	
		}

Is it possible you've got the comparison operators wrong?

I.e.


        if (ball.ballCircle.intersects(paddle.paddleRect)) {
            //left (was <=, now >=)
            if(ball.ballCircle.getMaxX() >= paddle.paddleRect.getMinX()){
                ball.ballCircle.setCenterX(paddle.paddleRect.getMinX()-ball.ballCircle.getRadius()-1);
                ball.setDx(-ball.getDx());
            }
            //Right (was >=, now <=)
            if( ball.ballCircle.getMinX() <= paddle.paddleRect.getMaxX()){
                ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()+1);
                ball.setDx(-ball.getDx());
            }
            //Top (was <=, now >=)
            if(ball.balllCircle.getMaxY() >= paddle.paddleRect.getMinY()){
                ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-1);
                ball.setDy(-ball.getDy());
            }    
        }
 

Matt

Hello, I would recommend adding an extra if statement, assuming that your x velocity is dx, make sure that the velocity is not already going the appropriate direction, and possibly remove the manual positioning before that. Run it all from adjusting the velocity of the ball. That way, you just check if it needs to change direction based upon the collision, and fix it if it does need to.


if (ball.ballCircle.intersects(paddle.paddleRect)) {
			//left
			if(ball.ballCircle.getMaxX() <= paddle.paddleRect.getMinX() && ball.getDX() > 0){
				
				ball.setDx(-ball.getDx());
			}
			//Right
			if( ball.ballCircle.getMinX() >= paddle.paddleRect.getMaxX() && ball.getDx() < 0){
				ball.setDx(-ball.getDx());
			}
			//Top
			if(ball.ballCircle.getMaxY() <= paddle.paddleRect.getMinY()){
				ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-1);
				ball.setDy(-ball.getDy());
			}	
		}

Think I have those right...

I've tried both suggestions and neither one seems to work. As for the second suggestion, if you hit the paddle near the edge, the ball just goes right through the paddle. I cant quite place my finger on what's wrong here.

Weird... I would have thought it would work. So, I programmed a breakout game myself last night using libgbx, and now that I have internet access here is the paddle collision. (It works great for me)

If you want more code, let me know, though the ball ricochets from the bricks sometimes in a way I didn't mean it to when doing initial coding (down if two bricks, easy enough fix, but what are you going to do in an hour?).


if (Intersector.overlapCircleRectangle(ball, paddle)
							&& ball.getyVelocity() < 0) {
						float totalVelocity = MathUtils.random(
								Ball.MIN_TOTAL_VELOCITY,
								Ball.MAX_TOTAL_VELOCITY);

						// need offset from center of paddle
						float xPercent = (ball.x - paddle.x - (paddle.width / 2f))
								/ (paddle.width / 2f);
						if (Math.abs(xPercent) > .95f) {
							if (xPercent > 0) {
								xPercent = .95f;
							} else {
								xPercent = -.95f;
							}
						}

						ball.setxVelocity(totalVelocity * xPercent);
						ball.setyVelocity(totalVelocity
								* (1f - Math.abs(xPercent)));
					}

Okay, I think I have it fixed now. I changed it to the following and after a few tests, it seems to hold. What was happening was that if you hit the paddle right on the corner, the overlap on the Y-axis was coming out to a really large number for some reason and bypassing my collision check. Any ideas why the overlap would be so large? I'm curious now about why that happened.


		if (ball.ballCircle.intersects(paddle.paddleRect)) {
			//Top
			//left
			if(ball.ballCircle.getMaxX()-ball.getAbsDx() <= paddle.paddleRect.getMinX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()-ball.getAbsDx());
				ball.setDx(-ball.getDx());
			}
			//Right
			else if( ball.ballCircle.getMinX()+ball.getAbsDx() >= paddle.paddleRect.getMaxX()){
				ball.ballCircle.setCenterX(paddle.paddleRect.getMaxX()+ball.ballCircle.getRadius()+ball.getAbsDx());
				ball.setDx(-ball.getDx());
			}	
			else{
				ball.ballCircle.setCenterY(paddle.paddleRect.getMinY()-ball.ballCircle.getRadius()-ball.getAbsDy());
				ball.setDy(-ball.getDy());
			}
			solidSound.play();
		}

This topic is closed to new replies.

Advertisement