碰撞变乱

源代码 2024-10-1 16:14:58 6 0 来自 中国
书名:代码本色:用编程模拟天然体系
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
目次
5.13 碰撞变乱

1、Box2D的另一个特性——碰撞

  Box2D通过“接口”提醒碰撞变乱发生的时候,在这里,我们有必要学习接口的相干知识,这是面向对象编程的一项高级特性。
你可以检察Java接口教程(http://download.oracle.com/javase/tutorial/java/concepts/interface.html)和JBox2DContactListener类的文档。2、PBox2D的碰撞


  • 如果你利用了PBox2D,就不必要用接口实现物体碰撞。在PBox2D中,碰撞变乱的检测是通过一个回调函数完成的,就像Processing中的mousePressed()函数:鼠标被点击时,mousePressed()函数就会被触发。两个物体发生碰撞时,beginContact()函数会被触发。
  • PBox2D有4个碰撞回调函数。
    1.beginContact()——两个形状刚开始打仗时触发这个函数。
    2.endContact() ——两个形状碰撞结束时触发这个函数。
    3.preSolve() ——在Box2D开始处置惩罚碰撞效果时被触发,也就是
    在beginContact()函数之前触发,该函数可用于制止一次碰撞。
    4.postSolve()——在Box2D处置惩罚完碰撞效果后被触发,该函数允许你网络“碰撞处置惩罚”(也称为“打击”)的相干信息。
3、beginContact()函数的利用方式

void beginContact(Contact cp) {
}

  • 留意上面的函数有一个Contact范例的参数,Contact对象包罗一次碰撞的全部数据——多少信息和力的数据。假设有一个Sketch步伐,此中包罗很多粒子对象,每个对象分别有一个Box2D物体对象引用,接下来我们要处置惩罚它们之间的碰撞。
步骤1:

Contact对象,你能否告诉我哪两个物体发生了碰撞

  • 是什么东西发生了碰撞?
    物体,形状,还是夹具?Box2D通过形状检测碰撞,由于只有形状对象拥有多少形状。但形状通过夹具毗连到物体上,因此我们应该向Box2D扣问:“你能否告诉我哪两个夹具发生了碰撞?”
Fixture f1 = cp.getFixtureA(); Contact对象存放了发生碰撞的夹具A和夹具BFixture f2 = cp.getFixtureB();步骤2:

夹具对象,你能否告诉我你毗连在哪个物体上
Body b1 = f1.getBody(); getBody()函数告诉我们夹具连在哪个物体上Body b2 = f2.getBody();步骤3:

物体,你能否告诉我你毗连在哪个粒子对象上

  • 这部分相对困难,由于Box2D对我们的代码一无所知。它只是负责管理形状、物体和关节之间的接洽,管理Processing对象和Box2D对象的任务在我们自己身上。荣幸的是,Box2D提供了getUserData()函数和setUserData()函数,通过这两个函数,我们可以将一个Processing对象(粒子对象)毗连到Box2D物体上。
  • 粒子类的构造函数负责创建物体对象。在创建过程中,我们要再参加一些代码,如下所示:
class Particle {    Body body;    Particle(float x, float y, float r) {        BodyDef bd = new BodyDef();        bd.position = box2d.coordPixelsToWorld(x, y);        bd.type = BodyType.DYNAMIC;        body = box2d.createBody(bd);        CircleShape cs = new CircleShape();        cs.m_radius = box2d.scalarPixelsToWorld(r);        body.createFixture(fd,1);        body.setUserData(this); “this”指当前的粒子对象,我们让Box2D对象存放这个粒子对象      }  }在addContact()函数中,一旦我们知道了碰撞的物体,就可以通过getUserData()函数获取物体对应的粒子对象。
4、示例代码5-9 碰撞监听

void beginContact(Contact cp) {    Fixture f1 = cp.getFixtureA();    Fixture f2 = cp.getFixtureB();    Body b1 = f1.getBody();    Body b2 = f2.getBody();    Particle p1 = (Particle)b1.getUserData(); 当我们从“用户数据”对象中抽取物体对象时,需    Particle p2 = (Particle)b2.getUserData();    p1.change(); 一旦有了粒子对象,我们就可以对它做任何事变。在这里,我们调用change函数,改变    p2.change();}

  • 在很多环境下,我们不能假设碰撞的物体都是粒子对象。Sketch中大概同时存在界限对象、粒子对象、盒子对象等。所以,我们必要查询这部分“用户数据”,并核实对象范例。
Object o1 = b1.getUserData(); 获取一个泛型对象if (o1.getClass() == Particle.class) {    Particle p = (Particle) o1; 扣问对象是否为Particle    p.change();}

  • 还必要留意一点,在Box2D触发这些回调函数时,你不能在beginContact()、endContact()、preSolve()或者postSolve()函数中创建或烧毁任何Box2D对象。如果你有这方面需求,可以在对象内部设置一个变量(诸如:markForDeletion = true),然后在draw()函数中查抄并删除相应的对象。
5、运行效果

1.gif
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 16:49, Processed in 0.173697 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表