当前位置: 首页 > news >正文

游戏引擎学习第50天

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

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

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

相关文章:

游戏引擎学习第50天

仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认…...

快速理解类的加载过程

当程序主动使用某个类时,如果该类还未加载到内存中,则系统会通过如下三个步骤来对该类进行初始化: 1.加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个…...

医院跌倒检测识别 使用YOLO,COCO ,VOC格式对4806张原始图片进行标注,可识别病人跌倒,病人的危险行为,病床等场景,预测准确率可达96.7%

医院跌倒检测识别 使用YOLO,COCO ,VOC格式对4806张原始图片进行标注,可识别病人跌倒,病人的危险行为,病床等场景,预测准确率可达96.7% 数据集分割 4806总图像数 训练组70% 3364图片 有效集20&#…...

[Unity Shader] 【游戏开发】【图形渲染】Unity Shader的种类2-顶点/片元着色器与固定函数着色器的选择与应用

Unity 提供了不同种类的 Shader,每种 Shader 有其独特的优势和适用场景。在所有类型的 Shader 中,顶点/片元着色器(Vertex/Fragment Shader)与固定函数着色器(Fixed Function Shader)是两种重要的着色器类型。尽管它们具有不同的编写方式和用途,理解其差异与应用场景,对…...

浏览器端的 js 包括哪几个部分

一、核心语言部分 1. 变量与数据类型 变量用于存储数据,在 JavaScript 中有多种数据类型,如基本数据类型(字符串、数字、布尔值、undefined、null)和引用数据类型(对象、数组、函数)。 let name "…...

GoogLeNet网络:深度学习领域的创新之作

目录 ​编辑 引言 GoogLeNet的核心创新:Inception模块 Inception模块的工作原理 1x1卷积:降维与减少计算量 1x1卷积的优势 深度分离卷积:计算效率的提升 深度分离卷积的实现 全局平均池化:简化网络结构 全局平均池化的作…...

深入C语言文件操作:从库函数到系统调用

引言 文件操作是编程中不可或缺的一部分,尤其在C语言中,文件操作不仅是处理数据的基本手段,也是连接程序与外部世界的重要桥梁。C语言提供了丰富的库函数来处理文件,如 fopen、fclose、fread、fwrite 等。然而,这些库…...

Java序列化

Java序列化 简单来说: 序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。最直接的原因就是某些场景下需要…...

基坑表面位移沉降倾斜自动化监测 非接触式一体化解决机器视觉

基于变焦视觉位移监测仪的基坑自动化监测新方案是一种集成了光学、机械、电子、边缘计算、AI识别以及云平台软件等技术的自动化系统。该方案利用变焦机器视觉原理,结合特殊波段成像识别技术和无源靶标,实现了非接触式大空间、多断面、多测点的高精度水平…...

提升效率:精通Windows命令行的艺术

文章目录 引言1. 基本目录操作命令dir:列出目录内容cd:更改目录mkdir 和 rmdir:创建和删除目录 2. 文件操作命令copy:复制文件或目录move:移动或重命名文件/目录del:删除文件 3. 文件查看命令type&#xff…...

ESP32-S3-devKitC-1 点亮板上的WS2812 RGB LED

ESP32-S3-devKitC-1 板上自带了一个RGB LED,型号为 WS2812。 RGB LED 在板上的位置如下图所示。 为了点亮这个WS2812,需要确定这颗RGB LED连接到哪个GPIO上了。 下面是确定GPIO管脚的过程: 1、根据原理图 2、根据PCB布局图: 程…...

python调用matlab函数(内置 + 自定义) —— 安装matlab.engine

文章目录 一、简介二、安装matlab.engine2.1、基于 CMD 安装2.2、基于 MATLAB 安装(不建议) 三、python调用matlab函数(内置 自定义) 一、简介 matlab.engine(MATLAB Engine API for Python):…...

CAD c# 生成略缩图预览

代码如下: using (Transaction tr currentdb.TransactionManager.StartTransaction()){//当前数据库开启事务using (Database tempdb new Database(false, true)) //创建临时数据库(两个参数:是否创建符号表,不与当前文档关联){try{Bitmap …...

端点鉴别、安全电子邮件、TLS

文章目录 端点鉴别鉴别协议ap 1.0——发送者直接发送一个报文表明身份鉴别协议ap 2.0——ap1.0 的基础上,接收者对报文的来源IP地址进行鉴别鉴别协议ap 3.0——使用秘密口令,口令为鉴别者和被鉴别者之间共享的秘密鉴别协议ap 3.1——对秘密口令进行加密&…...

汽车电子元件的可靠性保障:AEC-Q102认证

AEC-Q102标准的起源与价值 随着汽车电子系统的日益复杂,电子器件必须能够在极端的温度、湿度、振动和电磁干扰等恶劣条件下保持性能。AEC-Q102标准由汽车电子委员会(AEC)制定,专门针对LED、激光二极管和光电二极管等光电器件&…...

主成分分析法大全(包括stata+matlab)

数据简介:主成分分析(Principal Component Analysis,PCA), 是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。在实际课题中,为了…...

ubuntu+ros新手笔记(五):初探anaconda+cuda+pytorch

深度学习三件套:初探anacondacudapytorch 系统ubuntu22.04 1.初探anaconda 1.1 安装 安装过程参照【详细】Ubuntu 下安装 Anaconda 1.2 创建和删除环境 创建新环境 conda create -n your_env_name pythonx.x比如我创建了一个名为“py312“的环境 conda cre…...

C++ List(双向链表)

是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个 信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定 的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中&#…...

ASP.NET|日常开发中读写TXT文本详解

ASP.NET|日常开发中读写TXT文本详解 前言一、读取 TXT 文本1.1 使用StreamReader类 二、写入 TXT 文本2.1 使用StreamWriter类 三、文件编码问题3.1 常见编码格式 四、错误处理和性能考虑4.1 错误处理4.2 性能考虑 结束语优质源码分享 ASP.NET|日常开发中…...

【机器学习】在不确定的光影中:机器学习与概率论的心灵共舞

文章目录 概率与统计基础:解锁机器学习的数据洞察之门前言一、概率论基础1.1 概率的基本概念与性质1.1.1 概率的定义1.1.2 样本空间与事件1.1.3 互斥事件与独立事件1.1.4 概率的计算方法 1.2 条件概率与独立性1.2.1 条件概率1.2.2 独立事件 1.3 随机变量1.3.1 随机变…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来&#xf…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...