当前位置: 首页 > 知识库问答 >
问题:

二维物理/碰撞公式不按预期工作

叶茂才
2023-03-14

我有一个2D平铺矩阵(目前是墙),对于每一个墙,我检查我的玩家的下一个矩形(下一个如它在下一帧中的位置)是否与该墙碰撞,如果是,我希望我的玩家站在它旁边,而不是进入它。

下面是我想出的公式(这只是针对左右碰撞):

//*move entity
if (KState.Down(Keys.W)) en.AddForce(new Vector2(0, -10));
if (KState.Down(Keys.S)) en.AddForce(new Vector2(0, 10));
if (KState.Down(Keys.A)) en.AddForce(new Vector2(-10, 0));
if (KState.Down(Keys.D)) en.AddForce(new Vector2(10, 0));

foreach(Item i in map.Items)
{
    //resolve left-right collision
    if (en.NextBody(elapsedTime).Intersects(i.Body))
    {
        //check distance between top left corners
        int distance = (int)Math.Abs(i.Position.X - en.Position.X);

        //stop player in his horisontal movement
        en.AddForce(new Vector2(-en.Force.X, 0));

        //place player next to the wall his about to collide with
        en.Position = new Vector2(en.Position.X - distance + i.Body.Width, en.Position.Y);
    }
}

//stop player in place
if (KState.Clicked(Keys.Space)) en.AddForce(en.Force*-1);

en.Update(elapsedTime);
**

它给了我这个结果(注意fps不稳定,目前矩形是32x32的正方形):

编辑1:我设法解决了正确的冲突问题。而不是上面的代码

int sign = Math.Sign(i.Position.X - en.Position.X);
en.AddForce(new Vector2(-en.Force.X, 0));
//wall is right and player is left
if (sign > 0) en.Position = new Vector2(i.Body.Left - en.Body.Width, en.Position.Y);
//wall is left and player is right
if (sign < 0) en.Position = new Vector2(i.Body.Right, en.Position.Y);

但是左侧碰撞的问题是一样的。我尝试了
如果(符号<0)en.position=new Vector2(I.body.right+1,en.position.y);
如果(符号<0)en.position=new Vector2(I.body.right-1,en.position.y);以防万一,但问题是一样的(在“..-1...”情况下播放器卡在墙上)。

编辑2:根据@Paste请求,这里是player类中NextBody(浮点elapsedTime)的代码。

public Rectangle NextBody(float elapsedTime)
{ return new Rectangle((int)(force.X * elapsedTime) + body.X, (int)(force.Y * elapsedTime) + body.Y, body.Width, body.Height); }

共有1个答案

麹浩瀚
2023-03-14

这就是正在发生的事情:

当岩石向左移动时,物体第一次碰撞时,算法按其应有的方式工作。它看到对象是重叠的,它将强制设置为vector2.zero,并移动en,使其接触的右侧。很好。您的对象被停止并在正确的位置。

下一帧发生的事情是事情出错的地方。设置力向量,然后调用nextbody()。让我们看看x坐标。它设置为:

(int)(force.X * elapsedTime) + body.X
 类似资料:
  • 问题内容: 有时在我的SpriteKit程序中,我的碰撞和接触(使用SKPhysicsBody)没有按预期触发或起作用。我想我已经设置了所需的一切,但仍无法获得正确的交互。我如何轻松检查将与建立碰撞的物体和物体建立碰撞? 问题答案: 为了帮助诊断这些类型的问题,我编写了一个可以在任何地方调用的函数,该函数将分析当前场景并生成一个列表,列出哪些节点与其他节点发生碰撞以及将通知我的场景发生哪些碰撞。

  • 我想在我的玩家剑上创建一个碰撞体,如果他攻击,他会检测到,并通过动画事件关闭/打开一个名为(伤害点)的游戏对象,这是一个附加的脚本,可以减去敌人的生命值。但是在某个地方它不能正确检测到。我试图添加OnDrawGizmos函数来查看我的球体对撞机,但即使将其变大,它也无法检测到。 我的问题最奇怪的是,我对我的怪物箱子和我的幻想玩家使用相同的代码,但对箱子有效,但对玩家无效。 我创建了一个名为 Pla

  • 本章节主要介绍 2D 物理与碰撞系统,3D 相关的部分请参考 3D 物理与碰撞系统。 Creator 里的 2D 物理与碰撞系统包括两个部分: 碰撞系统 Box2D 物理引擎 对于物理计算较为简单的情况,我们推荐用户直接使用碰撞组件,这样可以避免加载物理引擎并构建物理世界的运行时开销。而物理引擎提供了更完善的交互接口和刚体、关节等已经预设好的组件。可以根据需要来选择适合自己的物理系统。

  • 当我在中创建一个场景时,我经常需要两个节点在完全相同的或位置来创建一面墙。我添加了矩形物理体。它们都没有任何摩擦。 当我使一个spritendode在这些碰撞体上移动时(我对物理体使用冲量),它的行为就像在两个矩形之间有一个屏障,我需要“推”节点或使其跳过边界。正如我所说的,这些节点彼此完全一致,因此节点应该能够平滑地通过它们。 有什么建议吗? 如果你需要我正在使用的任何代码/图片,请询问。 编辑

  • 碰撞器 碰撞器 组件定义了物体用于物理碰撞的形状。碰撞器是不可见的,并且不需要与物体网格的形状完全相同。事实上,在游戏中,粗略的近似值通常更加有有效,并且微不可查。 最简单(也是最小性能开销)的碰撞器是所谓的 基本碰撞器。在 3D 中,包括 盒碰撞器、球形碰撞器、胶囊碰撞器。在 2D 中,包括 2D 盒碰撞器、2D 圆形碰撞器。可以为一个物体添加任意数量的基本碰撞器,从而创建 复合碰撞器。 通过灵

  • 从 v2.3.0 开始,Cocos Creator 新增了对 3D 物理与碰撞系统的支持。 Creator 的 3D 物理引擎基于 cannon.js 实现,提供了高效的组件化工作流程和便捷的使用方法。目前支持了刚体、Box/Sphere 碰撞组件、触发和碰撞事件、物理材质、射线检测等特性。 而 3D 碰撞检测系统 Builtin 是只有碰撞检测系统的物理模块。它没有复杂的物理模拟计算,这将使得游