I'm programming in Java and have the following problem:
I would like to do collision detection. For that, I need different types of BoundingBox
es. For the sake of example, let's say that I have entities that have a circular collision box and entities that have a rectangular bounding box. So I need two classes, BoundingBoxCircle
and BoundingBoxRectangle
to implement collision detection. Also, I would like to have an abstract class BoundingBox
that has the abstract method collidesWith(...)
, which takes as an argument some kind of BoundingBox
and returns whether it is currently colliding with some other BoundingBox
.
Now for the issue: I can't find a nice way to structure this programmatically. Essentially, I need to implement different collision detections between rectangles and circles (and potentially other shapes). I would also like to be able to call these methods "nicely". When I have a particular bounding box, say BoundingBoxCircle
, I would like to be able to call boundingBoxCircle.collidesWith(rectangle)
and have it dynamically dispatched to the method that handles circle-rectangle collision detection. However, this does not work:
public abstract class BoundingBox {
public abstract boolean collidesWith(BoundingBox b);
}
public class BoundingBoxCircle {
@Override
public boolean collidesWith(BoundingBoxRectangle b) {
...
}
}
Because the signature of the overriden method is not the same.
So I can think of two options:
- Provide all method signatures in the superclass
- Override
collidesWith
in all subclasses
The first one has the problem that I would have to provide thecircleCollidesWithRectangle
, rectangleCollidesWithCircle
(etc.) signatures in the BoundingBox
class, which is quite ugly, because I essentially have "information" in BoundingBox
which should really be part of its subclasses.
The second one has the problem that I would need to override the collidesWith(BoundingBox b)
method in each subclass, which means that I do not know which type b
is of - so I would have to check for all cases in every subclass; essentially:
class BoundingBoxRectangle extends BoundingBox {
@Override
public boolean collidesWith(BoundingBox b) {
if (b typeof BoundingBoxRectangle) {
...
} else if (b typeof BoundingBoxCirce) {
...
} else {
throw new IllegalStateException("unexpected type");
}
}
}
...which could lead to an insane amount of if-statements if I start programming more subclasses for BoundingBox
. It also has the disadvantage that I might forget to add an if-statement in the future, which are potentially hard to find, because I only throw an exception if the collision is checked for two specific entities.
I would really like to implement this in a way that let's me see missing methods at compile-time and does not require code repetition.