【问题标题】:LibGDX / Box2D: How to keep track of active Contacts between bodies?LibGDX / Box2D:如何跟踪身体之间的活动联系?
【发布时间】:2020-06-22 07:35:20
【问题描述】:

我正在使用 Box2D 使用 LibGDX 制作 2D(侧视图)汽车游戏。这辆车有一个前轮和一个后轮,它是“AWD”。当玩家“燃烧橡胶”时,我想为车轮接触地面的每个点渲染灰尘效果。为此,我的计划是

  1. 实现 ContactListener,并在 beginContact(Contact contact) 方法中找到其中一个固定装置接地而另一个固定装置为汽车车轮的联系人。
  2. 将这些联系人保存到(车轮特定的)数组中,该数组应该包含车轮的活动联系人(车轮可以多点接触地面,因此需要一个数组)。
  3. 在每次渲染调用期间,对于每个车轮阵列中的每个接触:获取接触位置,并计算该位置的车轮主体和地面主体之间的速度差。如果速度差矢量的长度大于某个阈值,则绘制尘埃效果(使用速度差矢量来定义尘埃粒子的速度和角度)。
  4. 当我的 ContactListener 的 endContact(Contact contact) 被调用时,从数组中删除联系人。

问题在于 LibGDX 似乎为每个 Box2D 联系人使用相同的联系人实例,即使它仍然处于活动状态,也会重写现有的联系人!这意味着,例如,如果后轮首先接触地面,然后是前轮,那么我保存到后轮接触数组中的 Contact 实例将被前轮的接触属性覆盖。另一个问题是,当我收到 endContact 时,我不知道哪个 Contact 真正结束了。

我是不是理解错了,或者这就是 LibGDX 的行为方式?是否有可能以某种方式调整此行为,或者是否有简单的解决方法?

(我想到的一个选择是继续收听 beginContact 和 endContact 呼叫,并只跟踪接触每个车轮的地面物体/固定装置,但是我必须在每一帧手动计算接触点,这听起来有点困难、昂贵和多余 - 因为 Box2D 无论如何都会在每个世界步骤中计算它)。

【问题讨论】:

    标签: libgdx box2d


    【解决方案1】:

    也许您可以创建一个 MyContactListener 实现 ContactListener 类。

    MyContactListener 类包含一个 MyContactInventory 对象,它是一个 Singleton 对象,其中包含您的联系人数组和几个方便的方法:

    • 添加联系人
    • 删除联系人

    beginContact 和 endContact 使用上述方便的方法将联系人添加/删除到您的数组中。

    然后你调用 world.setContactListener(new MyContactListener());

    希望对你有帮助!

    【讨论】:

    • 这听起来很像我已经拥有的,但问题是当我将 Contact 实例添加到我的数组时,当 Box2D 世界中出现新联系人时,同一个实例会被 LibGDX “覆盖” .那么我该如何访问原始联系人数据(例如职位)呢?
    • 将您的数组包装在一个单例类中。这样,每当您添加联系人时,它都会使用现有实例。
    • 嗯,我以前没有使用过单例,所以我必须研究一下。但我真的看不出它是如何工作的。例如:假设首先发生前轮接触,beginContact 以 com.badlogic.gdx.physics.box2d.Contact@53b05f10 作为参数调用。 100 毫秒后发生后轮接触 => LibGDX 修改了 Contact@53b05f10 以便它现在包含后轮接触数据(包括位置)。不管我最初以什么方式存储了原始的Contact实例,它怎么会在接触后200毫秒知道前轮接触位置?是什么让它保持更新?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多