I've decided to try to create a simple game engine and I appear to be stuck on how to check for collisions between different Collider types for my game objects without the need for using 'instanceof' repeatedly. For example, some game objects may use a SphereCollider and others may use an AABBCollider, both of which extend the Collider class.
Here is the code within my GameObject class.
public final boolean collidesWith(Collider c) {
if (this.collider instanceof Collider3D) {
if (c instanceof AABBCollider3D) {
if (((Collider3D) this.collider).collidesWith((AABBCollider3D) c))
return true;
} else if (c instanceof SphereCollider3D) {
if (((Collider3D) this.collider).collidesWith((SphereCollider3D) c))
return true;
} else if (c instanceof AABBCollider2D) {
if (((Collider3D) this.collider).intersects((AABBCollider2D) c))
return true;
}
} else if (this.collider instanceof Collider2D) {
// Do 2D collision stuff...
}
}
Collider3D class
public abstract class Collider3D extends Collider {
public Collider3D(RigidBody rigidBody) {
super(rigidBody);
}
public abstract boolean collidesWith(AABBCollider3D collider);
public abstract boolean collidesWith(SphereCollider3D collider);
public abstract boolean intersects(AABBCollider2D collider);
public abstract boolean intersects(CircleCollider2D collider);
}
AABBCollider3D class
public class AABBCollider3D extends Collider3D {
private final Cuboid collisionBounds;
public AABBCollider3D(RigidBody rigidBody) {
super(rigidBody);
this.collisionBounds = new Cuboid();
}
@Override
public void update() {
final Vector3f objectLocation = getRigidBody().getObject().getLocation().getPosition();
final Matrix4f transformMatrix = getRigidBody().getObject().getTransformationMatrix();
final float width = transformMatrix.m03();
final float height = transformMatrix.m13();
final float depth = transformMatrix.m23();
// Set the collision bounds' location
collisionBounds.getLocation().setPosition(
objectLocation.x,
objectLocation.y,
objectLocation.z);
// Set the dimension of the collision bounds
collisionBounds.setWidth(width);
collisionBounds.setHeight(height);
collisionBounds.setDepth(depth);
}
@Override
public boolean collidesWith(AABBCollider3D collider) {
// Check collisions...
}
@Override
public boolean collidesWith(SphereCollider3D collider) {
// Check collisions...
}
@Override
public boolean intersects(AABBCollider2D collider) {
// Check collisions...
}
@Override
public boolean intersects(CircleCollider2D collider) {
// Check collisions...
}
}
I would like to know if there is a better way of doing this, mainly for two reasons:
- I've heard using the 'instanceof' keyword to check object types in this way is a workaround for bad code design
- Adding custom Collider types in the future would require me to extend the logic here, as well as in my Collider class