[英]How can I improve my code design to remove the need for 'instanceof' in Java?
我決定嘗試創建一個簡單的游戲引擎,但我似乎被困在如何為我的游戲對象檢查不同碰撞器類型之間的碰撞而無需重復使用“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 類
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 類
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...
}
}
我想知道是否有更好的方法來做到這一點,主要有兩個原因:
為每個特殊的子類型在Collider
類型中添加一個方法。 這是一種退化的訪問者模式。
所以它看起來像:
interface Collider {
boolean collidesWith(Collider other);
// I've used the same name here,
// not necessary but makes things easier.
boolean collidedBy(AABBCollider3D collider);
boolean collidedBy(SphereCollider3D collider);
// ...
}
每個子類型將如下所示:
public class AABBCollider3D implements Collider {
public boolean collidesWith(Collider other) {
return other.collidedBy(this);
}
public boolean collidedBy(AABBCollider3D collider) {
// ... code for AABBCollider3D collided by AABBCollider3D.
}
public boolean collidedBy(SphereCollider3D collider) {
// ... code for AABBCollider3D collided by SphereCollider3D.
}
// ...
}
這將在Collider
子類型之間創建相互依賴關系。 為了減少這種分裂的影響,在需要的地方和不需要的地方之間划分類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.