如何做游戏的重处理关系之间移动的东西喜欢的球员,怪物,或对象和地板吗?是球员不断"陷入"地板和被反弹了吗?

两种方式作出反应的碰撞,我们发现移动的放回到他以前的位置之前发生碰撞,并测试新的位置移动之前看到如果这会导致碰撞,但是我看不出这些可能会处理一个平台,这一平台上升以上,并需要能够提升。我看着这个从2D游戏设计的角度来看,但我猜想同样的问题发生在3D游戏的设计。任何提示?任何参考文献,我要检查吗?谢谢。

有帮助吗?

解决方案

您可能想查看 GameDev.net 的重力常见问题解答 一些基本信息。

由于您正在制作游戏而不是高度精确的物理建模者,因此我们可以这样做 欧拉积分. 。如果您对准确性的需求增加,我认为使用的最流行的集成方法是 龙格-库塔 (RK4) 集成. 。对于简单的游戏,您很可能不需要这些,但它们肯定用于更高级的物理模拟和 3D 游戏。使用 RK4 的缺点是复杂性略有增加并且速度稍慢。虽然它非常准确,但现在,让我们继续使用好的欧拉。

我也问过类似的问题,“如何将重力应用到弹跳球游戏中”,并得到了几个很好的答案。您要做的第一件事是为您的游戏选择一个任意的重力常数。在我的弹跳球应用程序中,我使用默认重力常数 2000px/s。您需要使用这个重力常数来获得特定游戏所需的效果。

接下来,您需要确保独立渲染游戏并更新游戏对象。这是为了防止游戏中的对象在快速计算机上移动得非常快,而在慢速计算机上移动得非常慢。您希望对象移动的物理特性和速度独立于计算机速度。关于此的一篇好文章是 游戏物理:调整你的时间步长!.

那么我们该怎么做呢?您可以跟踪自上次调用 Update 方法以来已经过去了多少时间。我创建了 2 个线程,尽管这不是直接必要的。我有一个游戏更新线程和一个渲染线程。更新线程控制更新游戏中对象的位置。更新线程知道上次调用它的时间、当前时间,并从中计算自调用更新方法以来经过的时间。

为了应用重力,我们只需将重力常数乘以经过的时间加上物体的 Y 速度。

private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;

public void updateGame()
{
    currentTime = System.currentTimeMillis();
    float elapsedSeconds = (currentTime - previousTime) / 1000f; 

    foreach(GameObject gameObject in gameObjects)
    {
        // Apply gravity to velocity vector
        gameObject.velocity.y += (gravityConstant * elapsedSeconds); 

        // Move objects x/y position based off it's velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

这将根据速度矢量移动所有物体,并根据重力常数对它们施加重力。最重要的是,它独立于计算机速度!

为了回答你的另一个问题,是的,物体的 y 向量将不断受到重力“力”。所以它会不断地与地板碰撞。但是,您想做的一件事是使用 埃普西隆值 最终使游戏对象的速度为零。然后,在作为修剪过程一部分的碰撞检测期间,您通常可以跳过检查非移动物体是否与任何物体发生碰撞(但反之则不然!)。

我喜欢对碰撞做的事情是,一旦发现物体发生碰撞(相互穿透),我就会将它们推开,以将它们分开的最小平移距离(MTD)。这一步很关键,否则您会遇到游戏中经常出现的错误,即对象“粘”在一起并抖动移动。一旦它们分开,我就会计算我的碰撞响应。

使用这种方法,它将在您描述的上升平台场景中正常工作。平台会继续上升,游戏对象会利用自身与平台之间的MTD将自己分离出来,它自然会随之上升。

如果您需要有关碰撞响应的帮助,我建议您查看:

其他提示

在某些游戏中使用的一种方法是欺骗:有一个单独的状态行走VS在空气中。在行走中,游戏引擎可以确定是走到该表面的斜率,并且如果不太陡,移动在所述表面的方向上的字符以及给予字符适当的垂直相对于表面的位置。

至于物理,我已经变成verlet的一体化的风扇如 Gamasutra的:高级人物动作。它简化了物理更新方程(不必跟踪速度!),它简化了碰撞(没有调整速度!)。这就是说,它确实有如果你需要准确一些细微差别的。

一个最完整的教科书对这个问题是 实时检测碰撞 通过克里斯特埃里克森.他已经 一个伴侣的博客 太。埃里克兰格的 数学3D游戏的编程和计算机图形 是有用的。

我不是专门的游戏程序员,但这是我的理解:

  • 在具有“无限帧速率”的理想世界中,您将在碰撞发生的那一刻精确地检测到碰撞,并使用一些标准物理来模拟碰撞后物体的新速度和加速度(请参阅标准高学校机械教科书,或各种标题为“游戏程序员的物理”的书籍)
  • 实际上,由于您有固定的帧速率,因此物体仅以一定的粒度移动,因此您通常需要添加额外的技巧,例如提前计算物体在下一帧中行进的相对路径,并查看是否存在以下情况:路径相交
  • 如果它们确实相交,那么交点实际上是 估计, ,但稍微不准确的是,物体真正发生碰撞的点;然后你可以选择不关心并将该估计值作为交点并线性插值以获得碰撞点的速度,或者现在你发现它们将相交进行更精确的计算,以获得实际碰撞点/时间/速度

在除了造型的碰撞,一个好的方法是(或动量,或者只是速度取决于你的模拟的复杂性)也模拟能量的持续转移。当你的球员站在一个平台上,存储在对象代表平台的信息,以及物体的速度调整任何时候都可以直接应用这一变化的正是如此连接播放器或其他物体。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top