Я решил попытаться создать простой игровой движок и, похоже, застрял в том, как проверять наличие столкновений между различными типами коллайдеров для моих игровых объектов без необходимости повторного использования instanceof. Например, некоторые игровые объекты могут использовать SphereCollider, а другие могут использовать AABBCollider, оба из которых расширяют класс Collider.
Вот код в моем классе GameObject.
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...
}
}
Я хотел бы знать, есть ли лучший способ сделать это, главным образом по двум причинам:
- Я слышал, что использование ключевого слова instanceof для проверки типов объектов таким способом - обходной путь для неправильного проектирования кода
- Добавление пользовательских типов коллайдера в будущем потребует от меня расширения логики c здесь, так как ну как в моем классе коллайдера