java矩形碰撞检测_java – 在oop中实现碰撞检测器的最佳方法

这篇博客探讨了在Java中使用OOP实现矩形碰撞检测的不同方法。通过创建抽象类`Shape`并覆盖`collidesWith`方法,实现了根据具体形状类型执行不同碰撞算法。文中提到了两种实现方式,一种是直接调用静态碰撞检测方法,另一种是将碰撞代码保留在相关类中。此外,还提出了一种可扩展的`CollisionAlgorithm`和`Collider`设计,以动态注册和查找碰撞算法,以适应更多形状的碰撞检测需求。
摘要由CSDN通过智能技术生成

如果您不介意将碰撞检测代码放在对象本身中,则可以通过执行以下操作来消除检查的一面:

public abstract class Shape {

public abstract boolean collidesWith (Shape s);

}

public class Ball extends Shape {

@Override public boolean collidesWith (Shape s) {

if (s instanceof Block)

return Collision.blockBall((Block)s,this);

else if (s instanceof Ball)

return Collision.ballBall(this,(Ball)s);

else

return false;

}

}

public class Block extends Shape {

@Override public boolean collidesWith (Shape s) {

if (s instanceof Block)

return Collision.blockBlock(this,(Block)s);

else if (s instanceof Ball)

return Collision.blockBall(this,(Ball)s);

else

return false;

}

}

public class Collision {

public static boolean blockBlock (Block a,Block b) { ... }

public static boolean blockBall (Block a,Ball b) { ... }

public static boolean ballBall (Ball a,Ball b) { ... }

}

如果有必要,这也可以让你自由地为Shape中的Shapes的某些组合实现碰撞算法 – 你甚至可以摆脱碰撞Block.collideWithBall,Block.collideWithBlock和Ball.collideWithBlock,适当地调用它们,例如:

public abstract class Shape {

public abstract boolean collidesWith (Shape s);

}

public class Ball extends Shape {

@Override public boolean collidesWith (Shape s) {

if (s instanceof Block)

return collidesWithBlock((Block)s);

else if (s instanceof Ball)

return collidesWithBall((Ball)s);

else

return false;

}

public boolean collidesWithBall (Ball b) {

...

}

public boolean collidesWithBlock (Block b) {

...

}

}

public class Block extends Shape {

@Override public boolean collidesWith (Shape s) {

if (s instanceof Block)

return collidesWithBlock((Block)s);

else if (s instanceof Ball)

return ((Ball)s).collidesWithBlock(this);

else

return false;

}

public boolean collidesWithBlock (Block b) {

...

}

}

就个人而言,我更喜欢后者,因为它保留了相关类中包含的碰撞代码.请注意,Block.collidesWithBall是不必要的,因为可以使用Ball.collidesWithBlock.

每次添加新形状时,您仍然需要更新上面的代码.如果性能不是问题,你也可以这样做:

public abstract class CollisionAlgorithm {

public abstract boolean canCollide (Class extends Shape> a,Class extends Shape> b);

public abstract boolean collide (Shape a,Shape b);

}

public class Collider {

private static final List algorithms;

public static void registerAlgorithm (CollisionAlgorithm a) {

algorithms.append(a);

}

public static CollisionAlgorithm findAlgorithm (Class extends Shape> a,Class extends Shape> b) {

for (CollisionAlgorithm algo : algorithms)

if (algo.canCollide(a,b))

return algo;

return null;

}

public static boolean collide (Shape a,Shape b) {

if (a == null || b == null)

return false;

CollisionAlgorithm algo = findAlgorithm(a.getClass(),b.getClass());

if (algo != null)

return algo.collide(a,b);

algo = findAlgorithm(b.getClass(),a.getClass()); // try swapped order

if (algo != null)

return algo.collide(b,a);

return false;

}

}

// usage: first register algorithms

Collider.registerAlgorithm(new BallBallAlgorithm());

Collider.registerAlgorithm(new BallBlockAlgorithm());

Collider.registerAlgorithm(new BlockBlockAlgorithm());

// then

Shape myShape1 = ...;

Shape myShape2 = ...;

boolean collide = Collider.collide(myShape1,myShape2);

请注意:我在这里快速输入,这是为了说明一个概念 – 可以进行许多改进.例如,地图可以与两个Shape类一起使用作为提高性能的关键,或者可以为CollisionAlgorithm提供通用参数以消除转换形状的需要.但请记住,每次需要执行碰撞测试时,此方法都需要在算法容器中查找.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值