使用Rectangle.Intersects()无法正确检测碰撞

5
我正在为我的打砖块游戏使用一张单一的精灵纹理表作为主要纹理。这张图片如下: breakout_sprite_sheet 我的代码有点混乱,因为我使用了一个Point来创建两个元素,一个用来表示元素大小和其在纹理表上的位置,一个Vector用来表示其在视口上的位置和一个Rectangle代表元素本身。
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;

我的初始化也有点混乱,但它能按预期工作:

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);

还有这个图:

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

问题是我无法正确检测到碰撞,使用以下代码:

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

我做错了什么?

1个回答

4
你正在测试基于sourceRectangles的碰撞,这是针对精灵表纹理进行的。这些矩形(paddleRectangle, ballRectangle)是根据纹理坐标定义的,也就是这些精灵在表格上的位置。使用这些矩形进行碰撞测试没有任何意义。
你需要使用屏幕坐标进行碰撞,也就是说,你需要使用屏幕位置定义不同的矩形:
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;
}

我确实有两个不同的矩形(请参阅编辑后的帖子)。我相当确定在初始化方面有问题... - Daniel Ribeiro
@DanielRibeiro 我做了一些编辑,使其更清晰。尝试使用整个代码块进行碰撞检测。您的初始化是没问题的。 - neeKo
我明白sourceRectangles的问题。有没有更简单的方法来解决精灵表格问题,而不必为每个对象创建两个矩形? - Daniel Ribeiro
@DanielRibero 我不这么认为,事实上我相信你现在的做法是正确(预期)的。你问题中的代码(除了碰撞部分)是没问题的。或者你是在说我回答中的那两个额外的矩形吗? - neeKo
1
不,我只是在最佳实践和重复代码方面有点怪异。既然你的解决方案完美地解决了问题,那我现在就开始吧。非常感谢!我很高兴文档在一个简单的方法签名上就能澄清这么多问题! - Daniel Ribeiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接