Java: 检查矩形与多个对象的碰撞
Java: Checking rectangle collision against multiple objects
我一直在通过尝试一些 "game" 来学习 Java,开始时只是尝试让球跳起来。我有 3 个 classes(JumpingBall3、BallSprite3 和 Floor),并实现了某种重力、持续有效的跳跃以及对地板的撞击检测以阻止球无限下落。通过最后一点,我发现了未来发展的一个潜在问题。现在我有两个由 JumpingBall3 ("floor1" & "platform") 创建的楼层,我使用以下代码检测 BallSpite3 内的碰撞:
public boolean collision()
{
if (game.floor1.getBounds().intersects(getBounds()) || game.platform.getBounds().intersects(getBounds())) {
onFloor = true;
}
else
{
onFloor = false;
}
return onFloor;
}
如果我继续添加更多楼层或平台,"if" 条件在长度方面很快就会失控。有没有办法创建一个循环遍历在我的 JumpingBall3 class 中创建的所有可见 Floor 对象的方法?
我已经 post 在线编辑了完整的代码 here,在 post.
中包含它似乎有点冗长
创建包含所有对象的列表。然后在你想要检测的所有对象上使用一个循环(当然除了进行检测的对象)
最简单的做法是将所有要检查的对象保存在 Collection
中,例如 List
,然后遍历此 List
.
因此,例如,这里一个不错的选择是使用 Floor
的集合,我们对其进行迭代以检查是否与其中一个发生碰撞。
public boolean collision() {
boolean onFloor = false;
Rectangle rectangle = getBounds();
for (Floor floor : floors) {
if (floor.getBounds().intersects(rectangle)) {
onFloor = true;
break;
}
}
return onFloor;
}
假设您使用 Java 8 ,您可以依靠 Stream API
来做与下一个相同的事情:
public boolean collision() {
Rectangle rectangle = getBounds();
return floors.stream().map(Floor::getBounds).anyMatch(rectangle::intersects);
}
这个问题的一个可行的解决方案是让你的 "game world" 包含一个实体列表(其中一个实体可以是球或墙或游戏对象中的任何其他对象),并有一些机制来检测哪个实体靠近其他实体。这最终会调用某种类型的 entity.checkCollision(neighborEntity)
方法。
你仍然需要有不同的行为来与不同的实体发生碰撞。您可以通过让基础 Entity
class 具有一些可以关闭或打开的公共属性,或者存储可以直接应用于碰撞实体的行为来实现。
// within some game loop, check for collisions
for (Entity entity : collidableEntities)
{
ball.checkCollision(entity);
}
您的 classes 可能看起来像这样具有编程行为。
public Entity
{
public void applyCollisionBehaviorTo(Ball ball) { // Override to do something}
public void onCollision() { // Override to do something }
public collidesWith(Entity neighbor) { // your collision math }
public void checkCollision(Entity neighbor)
{
if (collidesWith(neighbor))
{
onCollision()
}
}
}
public Wall extends Entity
{
@Overide
public void applyCollisionBehaviorTo(Ball ball)
{
ball.reverseDirection();
}
}
public Ball extends Entity
{
@Overide
public void onCollision(Entity collidingEntity)
{
collidingEntity.applyCollisionBehaviorTo(this);
}
}
我一直在通过尝试一些 "game" 来学习 Java,开始时只是尝试让球跳起来。我有 3 个 classes(JumpingBall3、BallSprite3 和 Floor),并实现了某种重力、持续有效的跳跃以及对地板的撞击检测以阻止球无限下落。通过最后一点,我发现了未来发展的一个潜在问题。现在我有两个由 JumpingBall3 ("floor1" & "platform") 创建的楼层,我使用以下代码检测 BallSpite3 内的碰撞:
public boolean collision()
{
if (game.floor1.getBounds().intersects(getBounds()) || game.platform.getBounds().intersects(getBounds())) {
onFloor = true;
}
else
{
onFloor = false;
}
return onFloor;
}
如果我继续添加更多楼层或平台,"if" 条件在长度方面很快就会失控。有没有办法创建一个循环遍历在我的 JumpingBall3 class 中创建的所有可见 Floor 对象的方法?
我已经 post 在线编辑了完整的代码 here,在 post.
中包含它似乎有点冗长创建包含所有对象的列表。然后在你想要检测的所有对象上使用一个循环(当然除了进行检测的对象)
最简单的做法是将所有要检查的对象保存在 Collection
中,例如 List
,然后遍历此 List
.
因此,例如,这里一个不错的选择是使用 Floor
的集合,我们对其进行迭代以检查是否与其中一个发生碰撞。
public boolean collision() {
boolean onFloor = false;
Rectangle rectangle = getBounds();
for (Floor floor : floors) {
if (floor.getBounds().intersects(rectangle)) {
onFloor = true;
break;
}
}
return onFloor;
}
假设您使用 Java 8 ,您可以依靠 Stream API
来做与下一个相同的事情:
public boolean collision() {
Rectangle rectangle = getBounds();
return floors.stream().map(Floor::getBounds).anyMatch(rectangle::intersects);
}
这个问题的一个可行的解决方案是让你的 "game world" 包含一个实体列表(其中一个实体可以是球或墙或游戏对象中的任何其他对象),并有一些机制来检测哪个实体靠近其他实体。这最终会调用某种类型的 entity.checkCollision(neighborEntity)
方法。
你仍然需要有不同的行为来与不同的实体发生碰撞。您可以通过让基础 Entity
class 具有一些可以关闭或打开的公共属性,或者存储可以直接应用于碰撞实体的行为来实现。
// within some game loop, check for collisions
for (Entity entity : collidableEntities)
{
ball.checkCollision(entity);
}
您的 classes 可能看起来像这样具有编程行为。
public Entity
{
public void applyCollisionBehaviorTo(Ball ball) { // Override to do something}
public void onCollision() { // Override to do something }
public collidesWith(Entity neighbor) { // your collision math }
public void checkCollision(Entity neighbor)
{
if (collidesWith(neighbor))
{
onCollision()
}
}
}
public Wall extends Entity
{
@Overide
public void applyCollisionBehaviorTo(Ball ball)
{
ball.reverseDirection();
}
}
public Ball extends Entity
{
@Overide
public void onCollision(Entity collidingEntity)
{
collidingEntity.applyCollisionBehaviorTo(this);
}
}