I'm programming in Java and have the following problem:
I would like to do collision detection. For that, I need different types of BoundingBoxes. 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
collidesWithin 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.