Java 如何改进代码设计以消除对';instanceof';在爪哇?
我决定尝试创建一个简单的游戏引擎,我似乎被困在如何检查我的游戏对象的不同碰撞器类型之间的碰撞,而不需要重复使用“instanceof”。例如,某些游戏对象可能使用SphereCollider,而其他对象可能使用AABBCollider,两者都扩展了Collider类 下面是我的GameObject类中的代码Java 如何改进代码设计以消除对';instanceof';在爪哇?,java,oop,reflection,Java,Oop,Reflection,我决定尝试创建一个简单的游戏引擎,我似乎被困在如何检查我的游戏对象的不同碰撞器类型之间的碰撞,而不需要重复使用“instanceof”。例如,某些游戏对象可能使用SphereCollider,而其他对象可能使用AABBCollider,两者都扩展了Collider类 下面是我的GameObject类中的代码 public final boolean collidesWith(Collider c) { if (this.collider instanceof Collider3D) {
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...
}
}
碰撞类
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);
}
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...
}
}
aabbr3d类
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);
}
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...
}
}
我想知道是否有更好的方法,主要有两个原因:
为每个特殊子类型在碰撞器中添加方法。这是一种退化的访问者模式 所以它看起来像:
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
设计得很好,就不需要强制转换。是的,我编写了Collider类,但我对编程相当陌生,所以我可能没有以最好的方式完成它。目前,我在基类中为每种不同类型的对撞机提供了抽象方法来进行检查。有更好的方法吗?是的,你能展示碰撞器
类和碰撞器的2个子类吗?我还没有编写逻辑来实际检查每个碰撞器的碰撞,但我将展示碰撞器类和AABBCollider3D类作为一个例子。基本的Collider类目前是空的,所以我不会显示它。对不起,我对编程非常陌生,我不太清楚你的意思。它是否与我展示的Collider3D类相似,我在其中为我希望检查的每个Collider子类提供了一个抽象方法?