Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't detect collision properly using Rectangle.Intersects()

I'm using a single sprite sheet image as the main texture for my breakout game. The image is this:

breakout_sprite_sheet

My code is a little confusing, since I'm creating two elements from the same Texture using a Point, to represent the element size and its position on the sheet, a Vector, to represent its position on the viewport and a Rectangle that represents the element itself.

Texture2D sheet;

Point paddleSize = new Point(112, 24);
Point paddleSheetPosition = new Point(0, 240);
Vector2 paddleViewportPosition;
Rectangle paddleRectangle;

Point ballSize = new Point(24, 24);
Point ballSheetPosition = new Point(160, 240);
Vector2 ballViewportPosition;
Rectangle ballRectangle;
Vector2 ballVelocity;

My initialization is a little confusing as well, but it works as expected:

paddleViewportPosition = new Vector2((GraphicsDevice.Viewport.Bounds.Width - paddleSize.X) / 2, GraphicsDevice.Viewport.Bounds.Height - (paddleSize.Y * 2));
paddleRectangle = new Rectangle(paddleSheetPosition.X, paddleSheetPosition.Y, paddleSize.X, paddleSize.Y);

Random random = new Random();
ballViewportPosition = new Vector2(random.Next(GraphicsDevice.Viewport.Bounds.Width), random.Next(GraphicsDevice.Viewport.Bounds.Top, GraphicsDevice.Viewport.Bounds.Height / 2));
ballRectangle = new Rectangle(ballSheetPosition.X, ballSheetPosition.Y, ballSize.X, ballSize.Y);
ballVelocity = new Vector2(3f, 3f);

And the drawing:

spriteBatch.Draw(sheet, paddleViewportPosition, paddleRectangle, Color.White);
spriteBatch.Draw(sheet, ballViewportPosition, ballRectangle, Color.White);

The problem is I can't detect the collision properly, using this code:

if(ballRectangle.Intersects(paddleRectangle))
{
    ballVelocity.Y = -ballVelocity.Y;
}

What am I doing wrong?

like image 590
Daniel Ribeiro Avatar asked Oct 06 '22 15:10

Daniel Ribeiro


1 Answers

You're testing collision based on sourceRectangles for the sprite sheet texture. Those rectangles (paddleRectangle, ballRectangle) are defined in terms of texture coordinates - that is where those sprites are on the sheet. It makes no sense to test those rectangles for collision.

You need to use screen coordinates for collision, that is, you need different rectangles defined with screen positions:

Rectangle paddleViewportRectangle = new Rectangle(paddleViewportPosition.X, 
                                              paddleViewportPosition.Y, 
                                              paddleSize.X, 
                                              paddleSize.Y);

Rectangle ballViewportRectangle = new Rectangle(ballViewportPosition.X,
                                                ballViewportPosition.Y,
                                                ballSize.X,
                                                ballSize.Y);

if(ballViewportRectangle.Intersects(paddleViewportRectangle))
{
    ballVelocity.Y = -ballVelocity.Y;
}
like image 57
neeKo Avatar answered Oct 10 '22 03:10

neeKo