游戏对象和地板之间的重力碰撞?

发布于 2024-07-11 07:50:25 字数 236 浏览 7 评论 0原文

重力游戏如何处理玩家、怪物或物体等移动物体与地板之间的关系? 玩家是否不断地“掉进”地板并被弹回来?

我发现对碰撞做出反应的两种方法是将玩家移回碰撞前的先前位置,并在移动之前测试新位置以查看是否会导致碰撞,但我不知道这两种方法如何可以处理一个向上升起并需要能够举起玩家的平台。 我是从 2D 游戏设计的角度来看这个问题的,但我想同样的问题也会出现在 3D 游戏设计中。 有什么提示吗? 我应该查看哪些参考资料? 谢谢。

How do games with gravity handle the relationship between moving things like players, monsters, or objects and the floor? Is the player constantly "falling into" the floor and being bounced back up?

Two ways to react to collisions that I have found are moving the player back to his previous location before the collision, and testing the new position before moving to see if it would result in a collision, but I don't see how either of these could deal with a platform that is rising upwards and needs to be able to lift the player. I'm looking at this from a 2D game design perspective, but I imagine that the same problem occurs in 3D game design. Any hints? Any references that I should check out? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

欲拥i 2024-07-18 07:50:26

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

由于您正在制作游戏而不是高度准确的物理建模器,因此我们可以通过 Euler 集成来逃脱。 如果您对准确性的需求增加,我认为使用的最流行的集成方法是 Runge-Kutta (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 向量将不断受到重力“力”。 所以它会不断地与地板碰撞。 但是,您想做的一件事是使用 Epsilon 值 最终使游戏对象的速度为零。 然后,在作为修剪过程一部分的碰撞检测期间,您通常可以跳过检查非移动物体是否与任何物体发生碰撞(但反之则不然!)。

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

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

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

You might want to check out GameDev.net's Gravity FAQs for some basic info.

Since you are making a game and not a highly accurate physics modeler than we can get away with doing Euler integrations. If your need for accuracy increases the most popular integration method that I see used is a Runge-Kutta (RK4) integration. You most likely won't need these for a simple game but they definitely are used in more advanced physics simulation and 3d games. The disadvantage with using RK4 is slightly increased complexity and slightly slower. It is very accurate though, but for now, lets stick with good ole Euler.

I asked a similar question, "How do I apply gravity to my bouncing ball game", and got several good answers. The first thing you'll do is choose an arbitrary gravity constant for your game. In my bouncing ball application I use a default gravity constant of 2000px/s. You'll want to play with this gravity constant to get the desired effect for your particular game.

Next, you want to make sure that you are rendering your game and updating your game objects independently. This is to prevent your in-game objects from moving really fast on fast computers and slow on slow computers. You want the physics and speed with which your objects move around to be independent of the computer speed. A good article on this is Game Physics: Fix your timestep!.

So how do we do that? You keep track of how much time has passed since the last call to your Update method. I created 2 threads, although it isn't directly necessary. I have a game update thread and a rendering thread. The update thread controls updating the in game objects positions. The update thread knows when it was previous called, the current time and from that calculates the elapsed time since the update method was called.

To apply gravity we will simply add to the Y velocity of our object by our gravity constant multiplied by the elapsed time.

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;
}

That will move all your objects based on their velocity vector's and apply gravity to them based on your gravity constant. Best of all it does it independently of the computers speed!

To answer your other question, yes the objects will constantly have the "force" of gravity on their y vector. So it will be constantly colliding with the floor. However, one thing you want to do is use an Epsilon value to eventually bring your gameObject's velocity to zero. Then, during collision detection as part of your pruning process you can usually skip checking if a non-moving object is colliding with anything (not vice-versa though!).

What I like to do with collisions is once I find objects colliding (penetrating each other), I'll push them apart by their minimum translation distance (MTD) which seperates them. This step is key otherwise you will get the frequently seen bug in games of objects "stuck" together jitterly moving about. Once they are separated I calculate my collision response.

Using this method it will work fine in your described scenario of a rising platform. The platform will continue to rise, the gameObject will separate itself using the MTD between itself and the platform and it will naturally rise with it.

If you need help on the collision response I would suggest looking at:

∞觅青森が 2024-07-18 07:50:26

某些游戏中使用的一种方法是作弊:为行走和空中设置单独的状态。 行走时,游戏引擎可以确定所行走表面的坡度,如果不是太陡,则沿表面方向移动角色,并为角色提供相对于表面的正确垂直位置。

至于物理,我正在成为 Verlet 集成的粉丝,如 Gamasutra:高级角色中所述物理。 它简化了物理更新方程(不必跟踪速度!)并且简化了碰撞(不必调整速度!)。 也就是说,如果您需要准确性,它确实有一些细微差别

One approach used in some games is to cheat: have a separate state for walking vs in the air. While walking, the game engine can determine the slope of the surface being walked over and, if not too steep, move the character in the direction of the surface as well as giving the character the proper vertical placement relative to the surface.

As for physics, I'm becoming a fan of verlet integration as described in Gamasutra: Advanced Character Physics. It simplifies physics update equations (don't have to keep track of velocity!) and it simplifies collisions (don't have to adjust velocity!). That said, it does have a few nuances if you need accuracy.

南烟 2024-07-18 07:50:26

有关此主题的最完整的教科书之一是 实时碰撞检测,作者:Christer Ericson。 他还有一个配套博客。 Eric Lengyel 的3D 游戏编程和计算机图形学数学 也很有用。

One of the most complete textbooks on this subject is Realtime Collision Detection by Christer Ericson. He has a companion blog too. Eric Lengyel's Mathematics for 3D Game Programming and Computer Graphics is useful too.

甜警司 2024-07-18 07:50:26

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

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

I'm not specifically a games programmer, but this is my understanding:

  • in an ideal world with an "infinite frame rate", you'd detect the collision at precisely the moment it occurred, and use a bit of standard physics to model the new velocities and accelerations of the bodies following the collision (see a standard high school mechanics textbook, or various books entitled things like "Physics for Games Programmers")
  • in reality, because you have a fixed frame rate and hence bodies only move with a certain granularity, you usually need to add an extra trick, such as calculating in advance the relative path that bodies will travel on the next frame and seeing if any of the paths intersect
  • if they do intersect, then the point of intersection will actually be an estimate, but slightly inaccurate, of the point at which the bodies really would have collided; you then have the choice of not caring and taking that estimate as the point of intersection and linearly interpolating to get the velocities at the point of collision, or doing a more precise calculation now you've found out that they will intersect, to get the actual point/time/velocities of collision
禾厶谷欠 2024-07-18 07:50:26

除了对碰撞进行建模之外,一个好的方法是对能量(或动量,或只是速度,具体取决于模拟的复杂性)的连续传输进行建模。 当您的玩家站在平台上时,将该信息存储在代表平台的对象中,并且每当调整该对象的速度时,您都可以将该更改直接应用于由此链接的玩家或其他对象。

In addition to modeling collisions, a good approach is to also model continuing transfers of energy (or momentum, or just velocity, depending on the complexity of your simulation). When your player is standing on a platform, store that information in the object representing the platform, and any time the velocity of the object is adjusted you can directly apply that change to the thusly linked player or other objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文