【发布时间】:2015-03-27 12:07:41
【问题描述】:
我正在尝试一个简单的 Break Out 克隆,以了解游戏状态、游戏循环等。
我遇到的困难之一是碰撞检测。
我有一个由 Ball、Brick 和 Paddle 扩展的 GameItem 类。在这个类中,我有一个 getBounds() 方法来返回对象的边界矩形,一个碰撞(GameItem 项目)方法来确定 2 个 GameItem 对象是否发生碰撞以及 hitTop()、hitBottom() 的方法, hitLeft() 和 hitRight() 来确定对象的哪一侧与另一侧发生碰撞。
这些方法如下:
public Rectangle getBounds()
{
return new Rectangle(x, y, width, height);
}
public boolean collision(GameItem item)
{
return getBounds().intersects(item.getBounds());
}
public boolean hitTop(GameItem item)
{
return getY()+getHeight()>=item.getY();
}
public boolean hitLeft(GameItem item)
{
return getX()+getWidth()>=item.getX();
}
public boolean hitBottom(GameItem item)
{
return getY()<=item.getY()+item.getHeight();
}
public boolean hitRight(GameItem item)
{
return getX()<=item.getX()+item.getWidth();
}
ball 类有一个名为checkBallCollissions(GameItem item) 的方法来确定球何时击中另一个对象。如下:
public boolean checkBallCollisions(GameItem item)
{
if(this.collision(item))
{
if(this.hitTop(item))
{
this.setVY(-1*this.getVY());
return true;
}
else if(this.hitBottom(item))
{
this.setVY(-1*this.getVY());
return true;
}
else if(this.hitLeft(item))
{
this.setVX(-1*this.getVX());
return true;
}
else if(this.hitRight(item))
{
this.setVX(-1*this.getVX());
return true;
}
return false;
}
return false;
}
如下调用:
ball.checkBallCollisions(paddle);
如您所见,如果它碰到 4 个边缘之一,x/y 方向会相应地反转。
但是,这不起作用。分析代码似乎有一个明显的问题,我无法理解解决方案。
下面的 3 张图片显示了球与物体从上方、下方和右侧的碰撞。
按照现在的代码,它首先根据边界矩形和 intersects() 方法检测碰撞。然后它确定它击中了哪一侧。如果它从上面击中它就可以工作。但是,当它从底部或右侧击中时,hitTop() 将返回 true,因为 getY()+getHeight()>=item.getY() 在这两种情况下都为 true(即球的底部边缘的 y 值大于与它碰撞的对象的顶部边缘)。
我缺少什么条件来解决这个问题并进行完美的碰撞检测?
【问题讨论】:
-
请参阅Collision detection with complex shapes 了解工作示例。
标签: java swing awt collision java-2d