游戏引擎学习第50天

server/2024/12/18 23:48:53/

仓库: https://gitee.com/mrxiao_com/2d_game

Minkowski 这个算法有点懵逼

回顾

基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认为游戏正常运行所需的所有内容。这样一来,我们就有了一个基础框架,可以观察它如何工作,并确认每个部分的基本需求。

接下来,我们将根据这些代码做更加高效、工业化的版本。首先,我们还需要确保其他部分的代码已经就绪,这些代码可以在构建新组件时帮助我们确保整体功能的协调。这样,当我们开始开发新组件时,就能够以高质量的版本来实现,而不是脱离其他部分单独开发,因为在真空中开发往往会忽略与其他部分的接口,容易出错。

目前,我们已经达到了目标,碰撞系统已经基本运行了,比预期更好,尽管它可能没有预想中那么温和。接下来,我会为系统添加更多的特性,再进行一些调试,直到我们达到一个理想的版本。之后,最终版本会整合所有特性和功能。

另外,我们还需要添加一些东西,这些东西被认为是相对重要的,比如基础的颜色和纹理,这也是接下来要处理的内容。

好了,我们开始吧。

今天要做的事:滑行/滑冰和基于区域的碰撞检测

以下是内容的中文总结:

今天的目标有两个:

  1. 实现滑翔功能。希望能够沿着边缘滑动,而不是停下来。
  2. 实现基于区域的功能,这一点非常重要。现在角色的基础坐标只是bottom的位置,我们不希望它穿透其他物体。

首先,滑翔功能可能会比第二个功能更具挑战性,因为滑冰的数学原理已经讲解过了,所以可以比较容易地理解要做什么。现在需要讨论的是如何实现基于区域的功能。如果实现基于区域的功能需要花费大部分时间,那么滑翔功能可以推迟到周一来处理。

滑翔的实现并不会像预期的那样需要大量投入,因为数学原理已经处理过了。这不是一个巨大的挑战。

到目前为止碰撞检测回顾

我们曾经采用的方法是在碰撞检测中,只检查角色是否与墙壁发生接触,基本上是每一帧检查角色是否处于某个位置,并判断是否与其他物体发生碰撞。这样的方法有问题,因为它不能实现滑行效果,并且可能会导致类似隧道效应的问题(角色穿越物体)。此外,这样的方法也存在其他问题。

因此,决定改用一种新的方法,计算角色碰撞的具体时间点,即求解碰撞的交点。这样的方法可以让我们知道角色是否与墙壁发生碰撞。

为了简化计算,我们将碰撞检测简化为检查一条线段,假设角色只与四面墙发生碰撞。在这种简化的假设下,角色仅被视为一个点,而不是有面积的实体。这样,角色被认为沿着一条直线移动,这就是我们目前正在测试的情况。

接下来,我们需要讨论如何将其扩展,使角色不再是一个点,而是一个有面积的实体。

基于区域的碰撞检测(Minkowski 和积/差)

为了简化问题,我们将角色的形状设定为矩形,因为这样可以更容易实现。尽管实际上,我们讨论的理论对于不同形状是相同的,无论角色是矩形、圆形还是其他形状。然而,在实现时,不同的形状会需要使用更强大的算法进行处理。

接下来要讨论的内容是Minkowski算法,或者说是与Minkowski有关的差异。虽然Minkowski的工作非常重要,但并没有深入学习他的代数知识和形状处理方法。尽管如此,理解这些内容可以带来很多有趣的可能性,如果能深入理解这些概念,将能够在实际的碰撞检测中得到很大的帮助。

关于Minkowski的具体工作,简化地说,主要是用来进行碰撞检测的工作原理。在理解了这些内容后,我们将能够更好地进行游戏开发,尤其是在处理不同形状的碰撞时。

Minkowski是一个数学概念,通常用于几何和碰撞检测领域,尤其是在计算机图形学和物理模拟中。最常见的是Minkowski和(Minkowski Sum)和Minkowski差(Minkowski Difference)。这些概念广泛应用于形状组合和碰撞检测的计算中。下面是对它们的简要说明:

1. Minkowski 和(Minkowski Sum)

Minkowski和是两种几何形状(如多边形、圆形、矩形等)的"组合"。具体来说,它是通过对其中一个形状中的每一个点与另一个形状中的每一个点相加,生成一个新的形状。

  • 定义:给定两个几何形状 A A A B B B,Minkowski和 A + B A + B A+B 是由形状 A A A 中的每个点与形状 B B B 中的每个点相加所形成的所有点的集合。
  • 公式
    A + B = { a + b ∣ a ∈ A , b ∈ B } A + B = \{ a + b \mid a \in A, b \in B \} A+B={a+baA,bB}
    其中, a a a 是形状 A A A 中的一个点, b b b 是形状 B B B 中的一个点, a + b a + b a+b 是两个点的向量和。

应用:在碰撞检测中,Minkowski和常常用来处理两个物体的碰撞。通过将两个物体的形状合并,可以更方便地判断它们是否发生碰撞,尤其是当物体是复杂形状时。

2. Minkowski 差(Minkowski Difference)

Minkowski差是另一种几何运算,它描述了两个形状之间的“差异”。它的结果是一个新形状,其中的每个点表示一个从一个形状(例如,物体1)到另一个形状(例如,物体2)的相对位置。

  • 定义:给定两个几何形状 A A A B B B,Minkowski差 A − B A - B AB 是通过将形状 A A A 中的每个点与形状 B B B 中的每个点相减所形成的所有点的集合。
  • 公式
    A − B = { a − b ∣ a ∈ A , b ∈ B } A - B = \{ a - b \mid a \in A, b \in B \} AB={abaA,bB}
    其中, a a a 是形状 A A A 中的一个点, b b b 是形状 B B B 中的一个点, a − b a - b ab 是两个点的向量差。

应用:在碰撞检测中,Minkowski差常用于判断物体是否相交。当Minkowski差的结果包含原点时,说明两个物体发生了碰撞。它有助于简化复杂形状的碰撞检测,特别是在GJK算法中广泛应用。

3. Minkowski 和与碰撞检测

Minkowski和和差在碰撞检测中的应用非常重要,尤其是在处理复杂形状(例如多边形、圆形、凸形状)时。在这些应用中,通常会使用如下技术:

  • GJK(Gilbert-Johnson-Keerthi)算法:这是一个基于Minkowski差的碰撞检测算法,用于判断两个凸形状是否相交。通过不断缩小搜索空间,GJK算法能够有效地检测复杂形状之间的碰撞。
  • EPA(Expanding Polytope Algorithm):当GJK算法确定物体相交时,EPA可以进一步计算出碰撞点和最小穿透深度。

4. 应用实例

  • 圆形与矩形的碰撞:可以通过计算Minkowski和将圆形和矩形合成一个新的形状,然后通过计算这个合成形状是否与其他物体相交,来检测它们之间的碰撞。
  • 滑行与碰撞:Minkowski和也用于滑行和边缘检测,例如当角色沿墙滑行时,Minkowski和可以帮助确保角色和墙之间没有重叠,避免穿透和错误的物理表现。

总结

Minkowski运算在碰撞检测中是一个非常强大的工具,尤其是在处理复杂形状和高效碰撞检测算法时。它通过将形状转换为更加简单的几何形式(如线段、矩形、圆形等),使得碰撞检测过程变得更加可控和高效。

示例:玩家大小穿过两个方块

我们讨论了如何将碰撞检测从点到具有实际尺寸的对象进行扩展。假设有两面墙,中间有一个缺口,墙的大小可以用一个维度来表示。为了简化问题,我们将墙的尺寸看作是方形的,而每个墙的“半径”定义为某种形式的维度。我们还假设一个人物对象,它有一个半径 r r r,并且我们希望它通过这两个墙之间的缺口。

如果按照传统的碰撞检测方式,即将人物看作一个点进行检测,那么当人物缩小到一个点时,它可以通过缺口,这是没有问题的。但是,如果人物有实际的尺寸(即它的半径为 r r r),那么显然它无法通过这个缺口,因为缺口小于 2 r 2r 2r。因此,简单的点碰撞检测方法无法处理具有实际尺寸的对象。

问题在于,如何进行碰撞检测,使得我们不仅能够验证物体是否会碰撞,还能模拟物体沿路径的连续运动。为了做到这一点,我们需要考虑代数形式的解决方法,这涉及到用代数运算来判断物体是否会与墙壁发生碰撞,并能够处理物体的实际尺寸。

这个方法的核心是扩展传统的点碰撞检测模型,将物体的尺寸纳入计算,从而能够处理具有实际物理尺寸的对象。这种方式让我们能够不断沿路径进行碰撞检测,并确保物体不会穿透任何障碍物。

Minkowski代数介绍:形状代数

我们讨论了如何在碰撞检测中处理具有实际尺寸的物体,而不仅仅是一个点。为了简化问题,假设有一个形状,我们可以将其看作是一个点,并尝试将碰撞检测应用于这些形状。假设墙壁的尺寸有一个半径 s s s,而物体本身也有一个半径 r r r。通过这种方式,物体将不再是一个点,而是一个具有实际尺寸的对象。

为了解决这个问题,我们采用了一种方法:通过对形状进行扩展,使得它们能够像一个矩形一样移动。这意味着我们将物体的形状扩展到它的周围边界,这样在进行碰撞检测时,物体就可以像一个矩形一样与其他形状交互。

具体来说,我们通过想象一个矩形扫过整个形状,生成一个新的形状。这种扩展形状的方法让我们能够更好地模拟物体的实际尺寸,并进行碰撞检测。通过将物体的“半径”加到墙壁的尺寸中,我们可以生成一个新的形状,并通过这个新的形状来检查碰撞。

这种方法解决了以前单纯使用点进行碰撞检测时的限制,让物体能够沿路径移动,同时避免穿越任何障碍物。通过这种方式,我们不仅可以避免物体与墙壁重叠,还能确保物体沿着路径顺利通过这些障碍。

总之,使用这种基于形状扩展的碰撞检测方法,我们能够实现更精确的物理模拟和更可靠的碰撞检测,从而更好地处理具有实际尺寸的物体。

在这里插入图片描述

回到 Minkowski 和积:矩形 + 圆形

我们讨论了如何将一个形状扩展成一个可以进行射线投射的点,通过这种方式,我们能更好地处理碰撞检测。具体来说,当我们希望将形状从一个实际的物体简化为一个点时,我们会通过“扩展”来为这个点创建一个类似于矩形的边界。为了更直观地理解这一过程,可以想象在形状周围扫一个圆形,这样就形成了一个带有圆角的矩形。

这种处理方式实际上是通过一种称为“Minkowski和差”(Minkowski sum and difference)的方法来实现的。我们将形状进行扩展,使其形成一个新的几何形状,这样在进行碰撞检测时,可以像处理矩形一样处理这些形状。这是通过将一个点的形状扩展到一定大小,模拟物体与其他物体交互的方式。

然而,虽然这个方法从概念上看起来是合理的,但实际上让计算机执行这一操作会非常复杂。尽管人类可以很容易地想象在形状周围扫一个圆形,问题在于如何用代码实际执行这一过程。
在这里插入图片描述

相似的形状

当处理 Minkowski 和时,如果两个形状完全相同,操作会非常简单。只需要扩展它们的半径即可。比如,如果有两个相同的矩形或圆形,将它们的维度相加,得到的结果就是将每个形状的边界扩展或增大。对于矩形来说,如果两个矩形相同,Minkowski 和就相当于扩展它们的半径,得到一个新的矩形。对于圆形,假设有一个半径为 (r) 的圆与一个半径为 (s) 的圆,它们的 Minkowski 和就是得到一个半径为 (s + r) 的圆。

这种方法在形状完全相同的情况下非常直观,操作简单,只需调整半径的大小即可得到合适的结果。

不相似且复杂的凸形状:GJK算法

当遇到不完全相同的形状时,Minkowski 和的计算会变得更加复杂。例如,如果一个矩形和一个圆形相加,得到的形状就比单一的矩形或圆形更复杂。为了处理这种情况,可能需要使用专门的射线投射算法或者将这些形状组合成一个复合形状,然后进行碰撞检测等操作。

对于复杂的形状组合,尤其是非凸形状,可以采用将形状分解为凸块的方式。通过将复杂的形状拆解为凸形状,可以利用较为高效的凸形状处理方法,比如凸形状的碰撞检测。常见的做法是使用如 GJK(Gilbert-Johnson-Keerthi)算法等,处理凸形状的碰撞检测和射线投射等问题。

对于大多数游戏,虽然可能不涉及过多的凹形状,但即便如此,考虑到复杂性,分解形状为凸块仍然是一个更高效的做法。这种处理方式也有助于提高碰撞检测系统的性能,尤其是在需要处理多边形、圆形等复杂对象时。

通过这种方式,复杂的形状可以通过合理的算法分解和优化,使得游戏中的碰撞检测更加高效和精确。

仅矩形的碰撞检测

在处理矩形和其他形状时,碰撞检测的实现其实并不复杂。通过增加半径或修改形状的周长,可以很容易地将形状转换为矩形,进而进行碰撞检测。例如,如果我们有一个圆形或矩形,我们可以通过加上适当的半径值,将其扩展成一个区域,然后再进行碰撞检测。这个过程中,通常需要将半径与物体的宽度和高度相结合,从而得到正确的碰撞区域。

在代码实现中,可以通过调整实体的半径,或直接增加某些“空白”区域来处理碰撞区的大小。这样就可以通过几行简单的代码,使得不同形状的物体都能够正确地进行碰撞检测。

虽然在一些情况下,可能会遇到复杂的错误或实现问题,但这些通常都可以通过逐步检查代码和逻辑来解决。通过确保每个步骤都被正确执行,可以有效避免错误并确保碰撞检测系统的正常运行。

最后,值得注意的是,碰撞检测不仅仅局限于简单的形状,实际上在处理复杂形状时,也可以通过将形状分解为更小的凸块来提高效率,这也是大多数游戏引擎和物理引擎中常用的做法。
在这里插入图片描述

在这里插入图片描述

考虑实体大小

在处理碰撞检测时,存在一个重要问题,即如何考虑实体的大小。虽然我们通常会根据每个瓦片的MinTile和MaxTile位置来循环遍历瓦片,但我们必须注意,实体的实际尺寸可能超出这些位置范围。实体可能会撞击距离当前位置更远的墙壁,因此我们不能仅仅考虑实体的中心位置或是碰撞框的简单边界,而需要计算出实体扩展后的真实影响区域。

为了确保正确处理这种情况,我们必须在循环遍历时考虑到实体的大小。具体来说,我们需要检查实体所在的MinCorner和MaxCorner,确定哪些瓦片会与这些扩展的区域发生重叠。这个步骤对于准确检测碰撞非常关键,特别是在处理具有较大尺寸的实体时。

当我们进行碰撞检测时,首先会根据实体的尺寸来确定它覆盖的瓦片区域。通过计算实体的大小在瓦片上的映射,我们可以扩展该区域,确保检测的瓦片包括实体实际可能碰到的所有区域。

通过这些改进,我们能够更准确地进行碰撞检测,避免漏检潜在的碰撞情况,也能提高游戏性能,减少不必要的计算。

在这里插入图片描述

碰撞的问题解决了不过还有粘性墙壁 问题碰撞之后不能动了

粘性墙壁出现

在碰撞检测过程中,出现了一些奇怪的现象。首先,发现实体在与墙壁碰撞时会变得很粘,这种情况比较令人困惑,尤其是在碰撞发生的另一边也是如此。开发过程中,预计会出现类似的行为,尤其是在较早期的碰撞检测机制中,这种“粘性”问题已经被考虑到并预期会发生。

一个可能的原因是,当前的碰撞检测系统可能依然使用了epsilon值来处理实体与墙壁的接触,导致其在碰撞时仍然被“卡住”。如果回忆一下,实体的位置应该是在墙壁附近,但实际上它被稍微移动了,使得在尝试沿着另一个方向移动时,它并不应该与墙壁发生碰撞。

该问题也涉及到实体的中心点偏移,特别是实体的高度绘制时并没有正确对齐。原本,实体的中心点应该是矩形的核心位置,而高度应该从该点开始进行计算,然而在现有的绘制方法中,高度被认为是从矩形的底部开始绘制的。因此,当实体与底部碰撞时,它的运动会停止,而碰撞检测系统将其视为半径值,这种处理方式并未完全符合预期。

解决方案的一个方向是,将碰撞检测方式调整为从实体的实际中心开始,而不仅仅是基于底部开始进行计算。这样可以使碰撞检测更为精确,同时能够更好地处理实体的宽度和高度问题。

总体而言,当前的碰撞检测系统中存在一些问题,但这些问题并非不可解决。通过进一步调整实体的中心位置和碰撞检测的算法,可以消除粘性问题,确保实体的运动更符合预期。
在这里插入图片描述

更改玩家的原点

在调整碰撞检测的过程中,首先,我们发现通过绘制实体时,当前的高度计算并不正确。具体来说,实体的高度应该从其中心点计算,而不是从底部开始。这是为了让碰撞检测能够正确处理,确保实体在碰撞时停止在合适的位置。

为了改进这一点,我们决定将高度调整为半个实体高度,确保实体的中心点与碰撞区域对齐。这样,碰撞时,实体能够按照预期的方式停止。尽管目前这已经是一个更正确的处理方式,但我们仍然认为需要进一步调整实体的尺寸,以更符合游戏的需要。

目前我们设定的实体高度并非实际的显示高度,而是为了碰撞检测所用的碰撞高度。实际的高度可能与此不同,因此我们还需要考虑实体的实际尺寸和碰撞检测的尺寸之间的关系。

我们可能需要重新评估如何定义和使用这些尺寸,尤其是在不同的游戏视角和视图下。最终,我们计划通过调整实体的宽度和高度,使其更符合实际需求,例如宽度设置为1,长度设置为0.5。这样,实体的尺寸更接近我们预期中的游戏角色外形,确保碰撞检测能够准确地反映实体的实际运动和停留状态。

总体来说,当前的调整使得实体的碰撞检测更加准确,尽管尺寸还需要进一步的优化,以确保符合游戏视角和预期的表现。

在这里插入图片描述

更多粘性墙壁调试

目前,区域碰撞已正常工作,但我们仍然遇到了“粘住”的问题,导致实体无法顺利移动。这似乎与速度更新有关,尤其是在实现滑翔功能之前。我们发现,碰撞检测器无法正确更新速度,导致实体停滞不前。具体来说,速度没有及时更新,因为我们在处理滑翔时并没有及时调整速度。

为了解决这个问题,我们首先检查了“最大瓷砖”设置,确保它能正确反映实体的实际运动。然而,问题仍然出现在碰撞检测和速度更新的同步上。当我们添加了对速度的处理后,问题得到了改善,但这并不是我们预期的最理想的解决方案。

在进一步测试中,我们确认,实际上如果我们继续实现滑翔功能,速度更新会自然而然地解决当前的困境。关键是,滑翔实现的完成可以自动修复现有的问题,而不需要额外的处理逻辑。总的来说,虽然我们发现了问题的根源,并尝试了一些调整,但最终的解决方案还是依赖于完成滑翔代码的实现。这使得整个过程更加简化,也证明了滑翔实现的重要性。
在这里插入图片描述

实现滑行

我们目前的工作进展良好,区域已经顺利运行,接下来要实现滑翔功能。

为了解决滑翔的实现问题,我们采用了类似之前的方法。基本的思路是,通过移除反弹速度,只保留剩余的速度来模拟滑翔。虽然逻辑和之前类似,但我们要将代码调整得更清晰。

首先,我们处理速度更新的方式,与之前的做法相同,只是这次我们通过内积运算来调整速度。这样,无论是否与墙壁发生碰撞,只要设置墙壁的法线为零,速度就能正确更新。

接下来,我们的重点是将墙壁的法线更新为击中墙壁的方向。对于墙壁的法线,我们选择一种通用方式,假设不管墙壁的倾斜程度如何,我们都会通过设置一个任意墙法线来更新速度。尽管现有的代码对水平和垂直墙面有效,但若涉及到斜墙时,代码可能需要做出相应调整。

另外,我们在测试时,通过设置不同的角度来验证法线的方向,以确保滑翔能在不同的情况下正确执行。通过这些调整,速度应该会得到正确的更新,从而使角色能够在游戏中顺利滑翔。

最后,通过验证,发现滑翔机制已正确运行。
在这里插入图片描述

碰撞时修正速度

我们现在需要解决最后一个问题。当玩家滑行时,速度更新并未完全停下,只有在玩家继续向墙壁靠近时,才会出现停止的现象。

为了解决这个问题,我们需要添加一个循环来持续更新速度,并修正与墙壁的碰撞。每次碰撞后,我们更新速度并继续移动,直到滑行的剩余距离完成。

我们通过迭代的方式来处理这个问题。初始时,我们计算出玩家的移动距离(delta),然后根据碰撞的情况不断调整这个距离。为了防止无限循环,设定了一个最大迭代次数,通常是4次。每次迭代后,我们会减少剩余的移动距离,并更新玩家的位置和速度。

在处理过程中,我们通过检查是否还存在剩余的滑行距离,来判断是否完成整个移动。当剩余的距离(t)降至零时,滑行过程结束。如果在多次迭代后,t未降到零,则说明滑行已完成。

每次碰撞后,我们更新玩家的位置并调整速度,使其不再试图穿越墙壁。这时,我们需要通过计算墙壁的法线,修正玩家的PlayerDelta,确保玩家不会再进入墙体。

最后,更新后的玩家位置和速度会被应用到游戏中,确保滑行效果达到预期。尽管目前仍然有一些细微问题,但基本思路和代码框架已经搭建完毕。
在这里插入图片描述

在这里插入图片描述

调试最终粘性错误

在这里插入图片描述

为什么英雄的头直径是1.5米?

英雄的头部大小设定为1.5米(即150厘米),在设计时可能是为了突出其风格化的外观。这个头部直径在游戏中的表现比较夸张,因为英雄的设计风格偏向于动漫风格,通常这种风格会使角色的头部比现实世界中的正常比例要大很多。尽管如此,这个比例显得有些不自然,与游戏世界中其他物体的比例相比显得过大。因此,考虑到角色的外观和游戏整体的美术风格,计划对英雄进行一定的缩小处理,以便让他与周围的环境更协调。然而,角色本身依旧会保持这种夸张的动漫风格,头部大小仍会显得较为突出。

如何用 Minkowski 处理凹形物体?

在游戏开发中,通常会有关于如何处理碰撞检测的讨论,尤其是对于凸多边形和凹多边形的处理。对于凸多边形之间的碰撞,使用“Minkowski”作为解决方案是一个非常有效的方法,这种方法也适用于处理凹多边形,只要通过适当的策略将其转化为多个凸多边形。在处理凹多边形时,尽管可能会面临计算成本较高的问题,但将凹面多边形拆分成凸面多边形依然是一种普遍且高效的做法。

对于三维游戏,碰撞检测技术依然可以应用相同的思想,尽管三维的额外维度带来了更高的复杂度。为了有效处理三维中的碰撞检测,可以将复杂的凹面形状拆分成多个凸面形状,这样在计算过程中可以更简化操作。

总体来说,碰撞检测的常见做法是将凹多边形分解为凸多边形,因为这样处理的计算会更加高效,并且适用于大多数场景和游戏环境。通过拆分凹形状,可以使用已有的凸形碰撞检测技术来简化问题处理。

资产的 alpha 通道是由艺术家创建的吗?

关于艺术资源的处理,阿尔法通道(透明度)通常是在艺术设计工具中自动生成的。在艺术家绘制图像时,阿尔法通道和颜色信息一起生成,这一过程是自动完成的。这样,源资产在生成时已经包含了所需的透明度信息,无需额外处理。

你做游戏已经多少年了?

做游戏开发确实是一项挑战,尤其是涉及到游戏引擎的编程时。这不仅仅是简单的实例化对象和依赖引擎来处理其余部分,更需要了解背后的复杂逻辑和技术。虽然有时这些任务对于初学者来说可能显得过于复杂,但通过手工实现这些功能,可以更清楚地看到其中涉及的每一个细节。即使你并不完全理解所有的内容,至少会对每一部分有更深入的了解,这将使你在未来的开发中更加得心应手。

学习游戏编程是一个艰难但非常有价值的过程,特别是对于那些想成为引擎程序员的人来说。这个领域不仅需要大量的理论学习,还需要通过实践来不断提高技能。由于学习曲线陡峭,游戏引擎程序员的数量相对较少,而且能够做到非常熟练的人更是凤毛麟角。掌握这些技能需要付出大量时间和努力,但最终能带来巨大的成就感和技能提升。

我通常只是希望帧率足够高,速度不会太快

在碰撞检测中,有不同的方式来处理物理计算,主要包括帧内迭代和时间步细分的方法。通过保持较高的帧率,可以确保物体的速度不会超过碰撞的大小,这是一个有效的解决方案。然而,如果物体的尺寸非常小,或者速度较快,则可能需要细分时间步,以确保每帧内都能正确地处理碰撞。这种方式虽然能解决问题,但可能会导致额外的计算开销。

另一种方法是通过将物理计算分解为更小的迭代步骤来处理碰撞,而不仅仅依赖于每帧一次的计算。这样做可以减少每帧需要处理的工作量,因为较高的帧率对物理计算的要求较高,可能会影响性能。通过在碰撞系统内部进行迭代,可以使计算集中在较小的循环范围内,这样在每次迭代时只进行最少的计算,从而提高效率。

总的来说,优化碰撞检测时,减少每次迭代内的工作量,尽量在较小的时间尺度内完成计算,并将其他部分推向更大的时间尺度,能有效提升性能。

你能用 Minkowski 算法处理旋转和对角线物体吗?

处理旋转碰撞时,存在不同的挑战,尤其是在动画旋转与静态旋转之间。对于静态旋转,传统的碰撞检测方法,如旋转矩形的碰撞,仍然有效,可以通过常规的几何方法进行处理。而当物体发生动画旋转时,问题就变得复杂,因为物体在旋转过程中会生成一个新的几何体形状(例如,一个矩形旋转后变成了一个八边形)。

在处理旋转的碰撞时,如果物体的旋转是在静态时间步内完成的,依然可以通过交叉测试来有效检测碰撞。这种方法通过计算物体旋转的“扫过体积”来处理碰撞检测。然而,对于动画旋转,问题在于旋转产生的形状可能变成凹形(例如,旋转过程中物体的边缘弯曲)。这种凹形无法像凸形那样直接进行有效的碰撞分解,因此必须通过进一步细分时间步来处理,增加了计算的复杂度。

为了应对这种问题,通常会简化旋转过程,只考虑旋转的开始和结束状态,而忽略中间的小幅度旋转。这样,碰撞检测可以通过简化的旋转角度来完成,这种方法在多数情况下效果较好。但如果需要完全精确地处理动画旋转,传统的旋转处理方法就无法适用,需要使用更复杂的算法或策略。

总体来说,动画旋转的碰撞处理非常具有挑战性,特别是在需要完全精确地模拟旋转过程中所有细节的情况下。为了避免复杂性,建议尽量将旋转细分为几个离散的方向进行处理,这样可以通过检查这些方向来简化碰撞检测。

是否可以制作一个让你在失败时继续的断言?

关于断言,理论上是可以设置断言使得在断言失败时程序继续执行。尽管目前没有这么做,但这是可以实现的,只是在当前的工作中并没有实施。将来可能会考虑在某些流中使用这样的策略,但目前来看,这在政治上并不重要。

如何表示一个大的横向卷轴2D世界?

在设计一个横向滚动的开放世界时,角色沿着地面行走,但不是平台式的跳跃或攀爬。对于地图的表示,瓷砖地图可能在垂直空间上会浪费,因此需要考虑如何优化。在分支路径的节点上,使用双链表可能会遇到性能问题。因此,可能的解决方案是使用类似平台游戏的稀疏方式进行布局。具体来说,可以通过稀疏地放置世界中的元素来实现,这种方式在生成世界时比较常见,也可能是最有效的方式。虽然目前尚不确定最终的实现方式,但很可能会更接近平台游戏的设计方式。

是否可以确定碰撞点?

已经在处理并确定碰撞点。当前的代码实现能够准确地确定碰撞发生的具体位置,这是通过精确计算完成的。这项工作在之前的一夜之间得以实现,并已成功应用。

看起来无法表示凸形物体是物理学中的一个主要问题

在物理引擎中,旋转通常不是最糟糕的问题。更常见的问题是接触检测,它通常比旋转更复杂且更难处理。虽然旋转是一个大问题,但它的非线性特性,尤其是在应用于接触时,才是真正棘手的部分。接触检测本身可能带来更多的困难,而旋转问题则更多是基于其对接触的影响。

我的意思是用通用的 GJK 算法确定碰撞点

在处理碰撞检测时,使用 GJK(Gilbert-Johnson-Keerthi)算法可能是最有效的选择。然而,手工编码的碰撞检测方法也可以作为替代方案,尤其是在特定情况下,像是通过手动编写碰撞逻辑来处理圆形、正方形和圆角矩形等形状的碰撞。虽然手工编码可能需要更多的工作,但它也能提供较高的灵活性和控制,能够处理复杂的碰撞检测和重叠测试。虽然不确定最终会采用哪种方法,但在某些项目中,手工编码方法曾经表现得非常好。

环路复杂度:代码中独立路径数的直接度量

直观地衡量线性独立路径的数量并不是计划中的分析内容,也没有打算进行这类分析。看起来所有的问题已经讨论完毕,暂时没有更多的疑问。


http://www.ppmy.cn/server/151294.html

相关文章

GIN

gin是什么 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧。 特点:gin是golang的net/http库封装的web框架,api友好,注…

用于日语词汇学习的微信小程序+ssm

日语词汇学习小程序是高校人才培养计划的重要组成部分,是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。本学生所在学院多采用半手工管理日语词汇学习小程序的方式,所以有必要开发日语词汇…

scala基础_数据类型概览

Scala 数据类型 下表列出了 Scala 支持的数据类型: 类型类别数据类型描述Scala标准库中的实际类基本类型Byte8位有符号整数,数值范围为 -128 到 127scala.Byte基本类型Short16位有符号整数,数值范围为 -32768 到 32767scala.Short基本类型I…

ctfshow-文件包含

78-php&http协议 GET传参,参数为file,没有过滤,直接包含 解法一(filter) payload: ?filephp://filter/readconvert.base64-encode/resourceflag.php得到一串base64,解码之后则为flag.php的内容 解法二…

C++小工具封装 —— NetWork(TCP、UDP)

在之前的文章中我们介绍到也写到基于TCP和UDP协议的网络通信。本篇我们又闲得无聊把这俩给封装成一个小工具以满足实际应用时多功能网络服务器的需要。 这个NetWork小工具是在Windows下制作的所以别忘了该有的头文件。C中编写我们就遵循面向对象的思想来。 #ifndef NETWORK_H …

开源分布式系统追踪-03-CNCF jaeger-02-快速开始

分布式跟踪系列 CAT cat monitor 分布式监控 CAT-是什么? cat monitor-02-分布式监控 CAT埋点 cat monitor-03-深度剖析开源分布式监控CAT cat monitor-04-cat 服务端部署实战 cat monitor-05-cat 客户端集成实战 cat monitor-06-cat 消息存储 skywalking …

TQ15EG开发板教程:使用SSH登录petalinux

本例程在上一章“创建运行petalinux2019.1”基础上进行,本例程将实现使用SSH登录petalinux。 将上一章生成的BOOT.BIN与imag.ub文件放入到SD卡中启动。给开发板插入电源与串口,注意串口插入后会识别出两个串口号,都需要打开,查看串…

【计算机视觉】医疗图像关键点识别

1. CNN 1.1. 设备参数 1.2. 代码 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader from torchvision import transforms from tqdm import tqdm import os import cv2 import numpy as np import time im…