我已经启动并运行了一个简单的BreakOut游戏(垂直,沿着底部划桨),但是碰撞检测有点问题。我最初使用Rectangle.Intersect来检查球是否与给定的砖块相交,然后如果它确实有4个交集调用来检查球是垂直碰撞(砖块的一侧,left+right)还是水平碰撞(砖块的top+bottom)。在某些情况下,当球在两块水平相邻的砖的交叉点附近以锐角碰撞一块砖时,球会移走这两块砖,并继续向上的方向。我假设这是两次碰撞。我已经强制退出了foreach循环,它会在找到矩形交集的瞬间检查它们是否相交,但这并没有解决问题。
这是在游戏类的主要Update()函数中:
foreach (Brick brick in bricks)
{
if (brick.CheckCollision(ball))
{
break;
}
}这是Brick.CheckCollision()函数:
public bool CheckCollision(Ball ball)
{
if (alive && ball.Bounds.Intersects(location))
{
alive=false;
ball.Deflection(this);
return true;
}
return false;
}这是Ball.Deflection()函数。在这里,我使用没有宽度/高度的矩形来标记砖块的侧面。不确定这是否是正确的方式:
public void Deflection(Brick brick)
{
//For vertical collision (top or bottom of brick) invert Y motion
if (this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Top, brick.Location.Right - brick.Location.Left, 0)) ||
this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Bottom, brick.Location.Right - brick.Location.Left, 0)))
{
motion.Y *= -1;
return;
}
//For horizontal collision (left or right side of brick) invert X motion
if (this.Bounds.Intersects(new Rectangle(brick.Location.Left, brick.Location.Top, 0, brick.Location.Bottom - brick.Location.Top)) ||
this.Bounds.Intersects(new Rectangle(brick.Location.Right, brick.Location.Top, 0, brick.Location.Bottom - brick.Location.Top)))
{
motion.X *= -1;
return;
}
}我假设我犯了一个明显的逻辑错误,但如果通用方法可以改进,我会洗耳恭听!
发布于 2012-09-10 17:07:36
通过与itsme86在评论中的讨论,我已经解决了我的问题。我添加了日志记录(由bmm6o推荐),并确认这是由于球在一帧的块内移动太远而在下一帧仍然部分位于相邻块内而导致的碰撞的加倍。我决定保持逻辑简单,当我反转它的方向时,只是把球移回它相交的区块边缘。这是在两个函数之间不使用Draw()函数以避免产生卡顿效果的情况下完成的。我正在努力观察任何跳跃或口吃,所以如果有任何跳跃或口吃,它是看不见的。
https://stackoverflow.com/questions/12309043
复制相似问题