Cocos2d-x 3 - 禁用两个物体之间的碰撞并检测它们何时相互分离
Cocos2d-x 3 - Disable collision between two bodies and detect when them separate each other
我正在开发 cocos2d-x 游戏(3.8 版)。我的游戏使用花栗鼠物理学,它有一个像中断器一样工作的静态 body。当另一个 body 在其上方时,此中断器将启用。当身体彼此分开时,中断器将被禁用。
我想:
- 移动body不要与中断器发生碰撞。它必须无弹跳地穿过中断器
- 我想在移动时检测body分离中断器
我的第一个方法是实现 onContactBegin 方法。当这两个机构接触时,我 return 错误。这样 body 就可以穿过中断器并且不会反弹。
问题是没有调用onContactSeparate方法,因为没有发生联系。
如果我在 onContactBegin 方法中 return 为真,则会调用 onContactSeparate 并且我可以检测到它。问题是 body 没有穿过中断器,它反弹了。
[编辑]更多信息
这是两个精灵分开的场景。球可以移动,中断器是静止的 body。球可能越过中断器。
这是两个精灵接触并且对象 1(球)在中断器上方的场景。我想检测两个精灵在哪里分开。
如有任何帮助,我们将不胜感激!
在我看来,您似乎在 cocos 中使用 Box2D,所以我将以此作为我的基本假设来回答。
这就是我要做的。
- 我的中断器将是一个 b2Body*,没有定义 BodyDef 尺寸或只有 0x0 尺寸定义。
- 我会将 bodyDef 的用户数据设置为描述我的中断区域的矩形。这样你就可以始终代表你的中断区域,但不会与任何东西发生碰撞。
(Optional) 如果你想让中断区域根据你分配给它的假体移动,你可以在这一步之后更新它使用如下所示的功能。
world->Step(delta, 10, 10);
for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext())
{
auto userData = static_cast<Node*>(physicsBody->GetUserData());
if(userData != NULL)
{
// Set interruptor area rectangle = physicsBody->GetPosition();
}
}
为了让系统的其余部分知道我何时离开中断器,我会存储一个函数指针,指向发生这种情况时要调用的函数,当对象进入中断区域时,我会标记它说 "I'm in the area" 在那之后,当它不再在该区域时你得到的第一个更新步骤我会触发回调并重置我用来达到那个点的标志。
希望对您有所帮助。你没有为你想做的事情提供很多背景信息,一张图片会很有帮助。尤其是在寻求具有可视化表示的代码方面的帮助时。
[编辑]
根据您想要的行为,这就是我这样做的方式。首先要知道的是,您不需要物理碰撞来实现您想要的行为。您可以通过使用边界框相交测试并使用标志和回调来找出其余部分来做到这一点。
我有一个对象,它知道球和我的中断节点。在此对象的更新循环中,我检查两者是否相交。我设置了一个 标志 指示 "I am in the interrupter",下一帧我不在中断器中并且我的标志仍然为真我调用我分配的函数 "leaving logic" 在其中,然后将标志设置回 false。
我正在开发 cocos2d-x 游戏(3.8 版)。我的游戏使用花栗鼠物理学,它有一个像中断器一样工作的静态 body。当另一个 body 在其上方时,此中断器将启用。当身体彼此分开时,中断器将被禁用。
我想:
- 移动body不要与中断器发生碰撞。它必须无弹跳地穿过中断器
- 我想在移动时检测body分离中断器
我的第一个方法是实现 onContactBegin 方法。当这两个机构接触时,我 return 错误。这样 body 就可以穿过中断器并且不会反弹。
问题是没有调用onContactSeparate方法,因为没有发生联系。
如果我在 onContactBegin 方法中 return 为真,则会调用 onContactSeparate 并且我可以检测到它。问题是 body 没有穿过中断器,它反弹了。
[编辑]更多信息
这是两个精灵分开的场景。球可以移动,中断器是静止的 body。球可能越过中断器。
这是两个精灵接触并且对象 1(球)在中断器上方的场景。我想检测两个精灵在哪里分开。
如有任何帮助,我们将不胜感激!
在我看来,您似乎在 cocos 中使用 Box2D,所以我将以此作为我的基本假设来回答。
这就是我要做的。
- 我的中断器将是一个 b2Body*,没有定义 BodyDef 尺寸或只有 0x0 尺寸定义。
- 我会将 bodyDef 的用户数据设置为描述我的中断区域的矩形。这样你就可以始终代表你的中断区域,但不会与任何东西发生碰撞。
(Optional) 如果你想让中断区域根据你分配给它的假体移动,你可以在这一步之后更新它使用如下所示的功能。
world->Step(delta, 10, 10); for (auto physicsBody = _world->GetBodyList(); physicsBody; physicsBody = physicsBody->GetNext()) { auto userData = static_cast<Node*>(physicsBody->GetUserData()); if(userData != NULL) { // Set interruptor area rectangle = physicsBody->GetPosition(); } }
为了让系统的其余部分知道我何时离开中断器,我会存储一个函数指针,指向发生这种情况时要调用的函数,当对象进入中断区域时,我会标记它说 "I'm in the area" 在那之后,当它不再在该区域时你得到的第一个更新步骤我会触发回调并重置我用来达到那个点的标志。
希望对您有所帮助。你没有为你想做的事情提供很多背景信息,一张图片会很有帮助。尤其是在寻求具有可视化表示的代码方面的帮助时。
[编辑] 根据您想要的行为,这就是我这样做的方式。首先要知道的是,您不需要物理碰撞来实现您想要的行为。您可以通过使用边界框相交测试并使用标志和回调来找出其余部分来做到这一点。
我有一个对象,它知道球和我的中断节点。在此对象的更新循环中,我检查两者是否相交。我设置了一个 标志 指示 "I am in the interrupter",下一帧我不在中断器中并且我的标志仍然为真我调用我分配的函数 "leaving logic" 在其中,然后将标志设置回 false。