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

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提供通用参数以消除转换形状的需要.但请记住,每次需要执行碰撞测试时,此方法都需要在算法容器中查找.

java碰撞检测_java – 在oop中实现碰撞检测器的最佳方法相关推荐

  1. react中绑定点击事件_在React中绑定事件处理程序的最佳方法

    react中绑定点击事件 by Charlee Li 通过李李 在React中绑定事件处理程序的最佳方法 (The best way to bind event handlers in React) ...

  2. java 字符串 字符查找_java之字符串中查找字串的常见方法

    1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引. int indexOf(String str, int startIndex):从指定的索引处开 ...

  3. java数组删除元素_java删除数组中的某一个元素的方法

    下面小编就为大家带来一篇java删除数组中的某一个元素的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 实例如下: package org.company.proj ...

  4. java读取pdf_Java 读取PDF中的文本和图片的方法

    本文将介绍通过Java程序来读取PDF文档中的文本和图片的方法.分别调用方法extractText()和extractImages()来读取. 使用工具:Free Spire.PDF for Java ...

  5. 什么是java枚举_java枚举的概念是什么?有哪些方法?

    java中关于枚举的知识点也是非常多的,枚举中的知识点可以细分成很多部分,想要全部掌握还是比较花费时间的.今天主要来简述一下枚举的一些基本的概念和方法,一起来了解一下吧. 首先说一下,枚举的概念. e ...

  6. java nio rewind_NIO-java.nio.ByteBuffer中flip、rewind、clear方法的区别

    原文链接     作者:Jakob Jenkov     译者:airu     校对:丁一 Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到 ...

  7. java 求导函数_在MATLAB中计算数值导数的最佳方法是什么?

    这些只是一些快速而肮脏的建议 . 希望有人会发现它们有用! 1. Do you have a symbolic function or a set of points? 如果您有符号功能,您可以分析计 ...

  8. java目录更改当前_Java-MVC:查看目录更改的最佳方法

    我将使用的方法是在WatchDir中提供用于注册回调的方法.最简单的方法是对回调使用 Consumer属性: public class WatchDir { private Consumer onCr ...

  9. 在jQuery中删除事件处理程序的最佳方法?

    我有一个input type="image" . 这就像Microsoft Excel中的单元格注释一样. 如果有人在与该input-image配对的文本框中input-image ...

最新文章

  1. 最优非对称加密填充(OAEP)
  2. Go 语言web 框架 Gin 练习 7
  3. IDEA修改Servlet的代码生成模板
  4. 新闻发布项目——业务逻辑层(categoryTBService)
  5. 单片机led闪烁代码_单片机、555实现LED闪烁电路
  6. Python 爬虫6——Scrapy的安装和使用
  7. java并发编程基础 --- 4.2 线程的优先级
  8. 一个前端小白的成长之路(序)
  9. Cobalt Strike参数详解
  10. webstorm激活破解
  11. 物联网标识管理系统源码
  12. 铁路订票系统的简单设计
  13. 财经大数据可视化Vdc平台_为何要使用大数据可视化平台
  14. Wps的两种论文标注参考文献
  15. 质心公式_No.217 质心位置的求法(基础篇)
  16. 编译项目时报出已经定义了构造器
  17. 使用Raygun Pulse进行真实用户监控
  18. mysql5.7 离线安装_Linux离线安装MySQL5.7
  19. Python绘制股票趋势图
  20. Qt大屏电子看板系统源码基础版

热门文章

  1. python中re模块及正则匹配
  2. 静静的分析华为Mate X的部分“亮点”,静静的围观它装逼!
  3. 追逐冠军的少年 | 算法工程师岗毕业三年总结
  4. 实验八 Python文件处理
  5. AI应用第一课:C语言支付宝刷脸登录
  6. PopupMenu弹出位置的控制
  7. 2013 NMPD展示预览,第1部分
  8. ps动感映像插件ImageMotion 1.3全新功能介绍
  9. 日记侠:如何用手机月入万元,只需从这5步开始
  10. 如何识别哭泣csdn_【jji技术】语音识别工程实战:聊聊语音芯片选型