游戏引擎学习第86天

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

回顾

继续之前的工作。
昨天已经让地形系统基本运行起来,但目前仍然需要进一步完善,使其能够生成更多的地块。目前的情况是,仅仅有一个地块位于中心区域,而真正需要的是让地块覆盖整个区域。
因此,首先要实现一个系统,使其能够遍历整个需要渲染的范围,并请求相应的地块,从而保证不会只有单个地块存在,而是让所有需要的地块都能正确生成。
接下来的工作就是从这个目标开始,逐步完善整个系统。

在这里插入图片描述

提案:首先生成覆盖区域的地砖……但它们不会是无缝的

首先,需要采取逐步推进的方式来完善地形系统。
第一步,先生成能够覆盖整个区域的地块,并确保在移动时,地块能够根据需求进行调整,使其始终出现在需要的位置。但这一阶段的地块不会是无缝衔接的,因此视觉上可能会出现明显的拼接痕迹,就像传统的瓦片地图游戏那样,每个地块之间存在可见的边界。
一旦这一部分工作完成并且能够正确运行,接下来需要进入下一个阶段,即确保地块之间能够无缝衔接。这两个部分是相互独立的任务——前者的重点在于如何正确填充地块,使整个区域被适当地覆盖,而后者则关注于如何调整地块内容,使其能够自然地衔接,消除明显的拼接痕迹。

处理如何指定所需的 ground_buffer

当前需要解决的问题是如何管理地面缓冲区的使用。现有的地面缓冲区是一个大数组,可以填充数据,但关键在于确定需要填充的世界位置。

首先,需要一种方式来标识哪些地面缓冲区是必要的,并确保这些缓冲区与世界坐标对齐。换句话说,需要一种方法来确定哪些世界位置应该填充到缓冲区中,并且确保填充时的世界单位能够与像素精确匹配,使得地面缓冲区的尺寸与世界坐标系统保持一致。

此外,时间因素也是需要考虑的部分,必须确保地面缓冲区在正确的时间点被放置到合适的位置。同时,缓冲区的大小需要与世界坐标系统保持对齐,确保每个像素与世界单位之间的映射关系是正确的,否则可能会导致数据错误或渲染不匹配。

当前的实现方式可能存在一定程度的误用,需要仔细思考如何优化分配和对齐策略,以确保整个地面缓冲系统能够高效运作。

停止对 GroundBuffer 进行测试填充

在当前的地面缓冲区(GroundBuffer)处理中,最初的实现包含一个测试填充(FillGroundChunk)步骤,该步骤用于填充第一个缓冲区。然而,该测试填充已经不再需要,因此需要将其完全移除。

为了替代这一过程,计划创建一个新的函数,用于执行所需的填充操作,并提供一个合适的工作位置。目前尚未确定该函数的调用位置或调用方式,但明确了它需要执行的操作。该函数将被添加到适当的部分,后续再根据需求调整具体的调用方式。
在这里插入图片描述

遍历摄像机可见的所有区域并请求 GroundBuffer

需要处理的任务是,为了确保相机能看到的每个区域都有相应的地面块(GroundChunk),必须创建一个方法来生成这些地面块。这将产生一个地面块的列表,用于填充所需的区域。

然而,地面块的存储方式使得检查是否存在某些地面块变得困难,因此需要想办法解决这一问题。为此,参考了模拟区域(SimRegion)的概念,其中有一个类似的区域计算方法。在该方法中,模拟区域的周围有一个“围裙”(apron),类似的策略可以应用于地面块的生成。

在这里插入图片描述

接下来,考虑到每个相机视野范围内的区域大小,计算出每个区域所需的地面块数。例如,如果视野是一个3x3的网格,那么就需要81个地面块。这一方法可以扩展到更大或更小的区域,具体取决于视野的大小。

实际操作时,需要用一个函数来请求生成地面缓冲区(GroundBuffer)。这个函数会接受区域的边界(Bounds)和世界坐标位置作为参数,世界坐标位置可以是区域的中心。通过计算,从中心位置开始,逐步填充该区域所需的地面块。

为了实现这一过程,中心坐标(CenterP)将被对齐到最接近的地面块位置。为了简化这一过程,可以忽略偏移量(Offset),直接使用已有的地块坐标数据来计算。通过这种方式,可以精确地将所需的地面块对齐到世界坐标系统中的正确位置。

还需要实现一个偏移操作,用来调整边界的位置,确保其与中心坐标对齐。这一操作非常简单,只需在原始边界的基础上进行偏移,类似于增加半径的操作。这个方法能够确保地面块的生成位置准确无误,满足相机视野的要求。

在这里插入图片描述

黑板:偏移量的考虑

当前处理的任务是基于一个矩形的中心位置(Center)和边界(Bounds)来调整矩形的位置。矩形的位置当前基于一个统一的坐标系统,并且有一个偏移量。需要的操作是,将矩形的中心从当前的位置调整为新的位置,从而使得新的矩形围绕目标点而不是原来的位置。

具体来说,原来矩形的最小点(Min)和最大点(Max)分别位于原位置,通过将矩形的偏移量加到这两个点来计算矩形的实际位置。现在,目标是将该矩形调整为围绕新目标位置,并且计算新的最小点和最大点。

为了实现这一点,关键是将偏移量包含在计算最大值(Max)时,确保新的矩形的边界位置是基于新中心点的。原本计算最大值时,会将偏移量与最大点相加,现在需要将偏移量间接地应用到最大点和最小点的计算中,从而调整矩形的定位。

这个过程的目标是使矩形的边界与新的中心点对齐。

减去偏移量

现在需要做的工作是通过计算矩形的偏移量,调整其边界位置。首先,通过将偏移量加到原始边界上,然后再从新的边界中减去这个偏移量,这样就可以得到一个没有偏移的矩形。通过这种方式,中心位置 CenterP 将不再有偏移量,而是对齐到一个新的标准位置。

接下来,处理过程将专注于 xy 轴的坐标调整,而 z 轴暂时不涉及。具体而言,将会处理类似之前提到的坐标(例如 AbsTilex),并考虑如何在空间中定位这些网格块。

目前还需要处理的是分块(chunks)在三个维度上的调整,包括 xyz,确保每个维度的块都可以根据新的坐标进行适当的调整。
在这里插入图片描述

考虑 Chunk 的大小

讨论的核心问题是每个地块(Chunk)的大小对整个地面缓冲区(GroundBuffer)管理的影响。当前地块的大小为16x16个瓦片,这可能过大,尤其是在处理精细的地面细节时,可能导致过大的地块不适合当前的地面缓冲区粒度。虽然这些瓦片在过去用于某些旋转操作,但现在它们已经不再是主要的工作单位,更多的是为地块的管理提供结构。

若地块与地面缓冲区能够对齐,那么地面缓冲区就可以直接与世界的布局同步,避免复杂的转换,甚至可以直接存储相关数据。这样做虽然有可能导致资源浪费,但理论上可以简化管理,使地面缓冲区的组织更加直接。

然而,将地面缓冲区存储在当前的结构中可能会显得过于冗余和不必要,增加了不必要的复杂性。尽管如此,这个方法仍然是一个有吸引力的选择,可能会尝试这一方案并观察其效果,以确定它是否能带来更简单的管理方式,尽管有些担心其可能带来的资源浪费问题。

简短插曲:查看 Chunk 的实际大小

讨论的核心是通过绘制实际地块(tile chunks)来了解这些地块的大小,并将其可视化,以便于评估它们在地面缓冲区管理中的适用性。首先,需要确定每个地块在屏幕上的实际显示大小,可以通过像素到米的转换来实现。通过计算摄像头区域的大小,将屏幕上的区域映射到世界坐标系中,从而绘制出对应的地块。

具体实现中,首先通过屏幕宽度和高度来计算它们对应的米值,然后使用这些值确定一个矩形区域,这个区域代表摄像头当前能看到的部分。接下来,使用这些信息来绘制包含地块的矩形,地块的大小可以通过已知的地块尺寸来计算。通过得到每个地块的位置与摄像头中心的差值,可以精确地在屏幕上绘制出这些地块。

其中,还涉及到地块中心位置的计算和绘制的转换,确保在正确的坐标上显示每个地块。遇到的问题是,绘制之前需要确保清除屏幕,避免覆盖之前绘制的内容。最终的目标是通过这种可视化方式验证地块尺寸是否合适,并评估其对地面缓冲区的影响。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在游戏中查看结果,并逐步调试代码

在这个过程中,首先屏幕被清除,接着获取了屏幕中心的坐标。随后,计算了屏幕的宽度和高度,并且转换为米作为单位,这些数值分别为22米和12米,这是第一次知道游戏场地的实际大小。

接下来,创建了相机视野的矩形(CameraBounds),并且将其转换为块空间。这个矩形的范围从负的20到12,显然这个设置是错误的。问题出在计算矩形时使用了“半维度”(half dim),但实际上应该使用“中心维度”(center dim),因为这里表示的是整个矩形的大小,而不是其一半。
在这里插入图片描述

在调整这个错误之后,继续将矩形映射到块空间,并检查了在块空间内最小和最大块的位置。结果显示,范围正确地从零到一,似乎是合理的。
在这里插入图片描述

接下来,检查了块中心位置的返回值,得到的结果与预期一致。然后,还查看了相对位置的返回值,确认它是符合实际情况的,也就是相机位置周围的正确坐标。
在这里插入图片描述

总的来说,问题的根本原因在于创建矩形时使用了错误的维度方式,这个错误已经被纠正,之后的计算和显示结果是合理的。
在这里插入图片描述

ChunkDimInMeters 乘以 MetersToPixels

在这个过程中,遇到了一些问题,主要是关于矩形的绘制和单位转换。首先,注意到目前所有的操作都使用的是米作为单位,但实际上应该转换成像素单位,这样才能正确显示在屏幕上。为此,需要在渲染时进行适当的单位转换,以确保可以正确地呈现矩形。

在这里插入图片描述

在这里插入图片描述

接下来,发现有两个问题。第一个是矩形的边框没有正确绘制,应该明确调用函数来绘制矩形的边框。第二个问题是矩形似乎总是与相机位置对齐,导致它出现了一些不期望的行为。这可能是由于相对位置计算时存在错误,需要进一步检查。

矩形的绘制和相对位置计算中,涉及到屏幕中心和矩形的相对位置的加和,初步看起来是合理的。但在实际渲染时,似乎出现了一些不明原因的偏差。为了更好地控制矩形的显示,计划使用一个边框绘制方法来明确绘制矩形的轮廓。最终目标是确保矩形正确显示并对齐。

总之,目前的问题集中在矩形的绘制和单位转换上,未来需要进一步调整这些设置,以确保渲染正确无误。

创建 DrawRectangleOutline

在这段调试过程中,首先提出了一个问题,即如何绘制一个矩形的边框。目标是通过新的绘制函数来实现矩形轮廓的渲染。计划中,新的函数应当采用与现有的绘制矩形函数相同的参数,并且转换为像素单位,而不是米单位。这是因为在显示时,需要在屏幕上准确地呈现矩形。

接下来,针对矩形的厚度进行了设置,选择了2像素的厚度,并尝试绘制矩形边框。为了简化绘制逻辑,矩形的最小和最大坐标被直接提取,并根据这些坐标生成矩形的外框线。

在实现时,采取了计算矩形边缘的方法。例如,在顶部和底部的绘制中,首先减去一个偏移量,然后再进行宽度的绘制;在左右边缘的绘制中,也按照类似的思路进行。通过这种方法,确保了矩形的每一条边都能够绘制出合适的线条。

此外,在调试过程中也进行了调整,尤其是在绘制过程中,设置了颜色和其他参数,以确保矩形的显示效果符合预期。最终,新的绘制函数被成功实现并测试,确保了矩形的边框能够正确渲染。

整体而言,这段调试流程展示了如何通过细化绘制矩形边框的逻辑,解决显示问题,并通过调整参数和简化代码来完成这一目标。
在这里插入图片描述

在这里插入图片描述

查看结果并分析 Chunk 位置信息的问题

在这里插入图片描述

遇到了绘制矩形时的一些问题,尽管计算结果接近正确,但仍然存在一些错误。首先,矩形的绘制功能与填充矩形的功能类似,但似乎没有达到预期效果。为了找出问题所在,首先回顾了矩形的绘制过程,特别是与视图和屏幕坐标的关系。

在调试过程中,检查了如何将每个区域的中心映射到相对屏幕中心的坐标。根据当前的计算,距离应该是正确的,但是实际绘制结果仍然不准确。还考虑了视口坐标与物理单位(米)之间的转换是否正确,特别是在从米转换到像素的过程中,发现了一些疑虑。

虽然觉得在当前情况下没有明显的错误,但仍然在疑惑是否有其他问题尚未发现。总的来说,怀疑可能是某些细节处理不当,导致了绘制的偏差,但还未找到具体的原因。

DrawRectangle 不接受宽度和高度参数

发现了一个错误,原本在绘制矩形时,误以为矩形的宽度和高度是直接传入的,但实际上没有正确处理这些值。问题出在调用绘制函数时,误将零作为参数处理,导致了不正确的结果。发现这个问题后,意识到需要重新计算屏幕的宽度和高度,确保在绘制时能正确地使用屏幕的尺寸。

最终,问题是由于没有正确处理屏幕尺寸和坐标转换所导致的。通过修正这些细节,矩形的绘制应该能够正常工作。
在这里插入图片描述

在这里插入图片描述

并且 Y 轴需要翻转

关于在处理渲染问题时遇到的一些困扰。具体来说,有提到在进行渲染时,遇到了常见的y轴翻转问题,虽然这个问题并不严重,但始终存在。尽管反复提到这个问题,仍然没有找到最优的解决方案,特别是在一开始是否应该引入渲染相关的内容上。对于何时应该做某些事情以及这些操作是节省时间还是浪费时间,感到不确定。有时答案很清晰,但有时却并不明确,尤其是在决定是否应该从一开始就处理某些问题时,显得特别困难。
在这里插入图片描述

在这里插入图片描述

进展顺利,但 Chunk 被绘制得太小

在渲染时,区块显示得太小。显然,区块的实际大小不应如此,因为如果按照这个大小,区块将无法覆盖所有内容。问题的原因是因为在计算时,误差导致大小偏小,实际上已经在处理时做了半个尺寸的调整,这就是导致问题的根源。
在这里插入图片描述

在这里插入图片描述

尝试将 Chunk 设为原来的四分之一大小

这段内容讨论了当前区块的大小问题,发现它们过大,不适合用于存储地面缓冲区点。于是考虑将区块大小缩小,尝试使用更小的块作为瓦片大小,以实现统一的尺寸。尝试将区块尺寸缩小至原来的四分之一后,发现这是一个更为可管理的大小,虽然可能稍微大了一点,但仍然可以接受,甚至可以尝试进一步缩小。考虑到使用这种尺寸的成本,决定尝试这种新的分辨率,并观察效果。
在这里插入图片描述

在这里插入图片描述

基于 256*256 块的大小来设置 Chunk 大小

现在可以根据需要设置区块大小,而不再考虑每个区块的瓦片数量。以前区块的大小是通过瓦片数量来决定的,但现在这个概念不再适用。可以反向计算所需的物理活动区域的大小,并将其作为区块的大小,以确保区块的尺寸与活动区域一致,从而使整个系统能够更好地协调工作。

MetersToPixels 成为整数

为了更好地协调渲染与世界的关系,可以考虑将米到像素的比例设置为整数,而不是目前使用的较为复杂的数值。这可以通过调整比例,使其成为类似于二的幂(例如32或64)这样的更友好的数值。通过这样做,世界的缩放会有所变化,但这种调整是为了确保渲染和世界尺寸之间的匹配更加合理。在这种情况下,可以灵活地调整瓦片尺寸,使其与新的比例相适应,从而获得更合适的大小。
在这里插入图片描述

在这里插入图片描述

评估 TileSideInMeters 是在哪里设置的,并考虑去掉它

在处理世界初始化时,TileSideInMeters 只是一个合成概念,主要用于世界创建和计算区块位置的转换。它的作用并不显著,因为只在创建过程中使用一次。考虑到这一点,可能不需要继续保留这个参数,去掉它可能会带来一些优化或简化。在这种情况下,去除它不会影响整体功能,反而可能在实现上提供一些好处。
在这里插入图片描述

InitializeWorld 中去掉 TileSideInMetersTileDepthInMeters

在初始化世界时,可以考虑不使用 TileSideInMeters,而是将其从代码中移除,看看会发生什么。对于需要使用这些值的地方,基本上只是为了世界构建或者碰撞检测而设定的尺寸,这些值都是任意的,可以根据需求调整。例如,碰撞检测的值是为了让物体的碰撞更符合预期,而这些参数本质上是根据实际需求设置的。除此之外,摄像机设置的参数也可以从屏幕尺寸推导出来,这样会更加灵活和精准。因此,移除 TileSideInMeters 可能并不会影响整体功能,并且能够简化实现过程。
在这里插入图片描述

直接传入 ChunkDimInMeters

在进行初始化时,需要直接传递 ChunkDimInMeters 的值,并且将其赋值给对应的变量。此时,TileSideInMeters 只是一个暂时使用的值,主要用于世界构建,因此可以暂时保留旧的值,并将其应用于当前的初始化过程。随着世界构建的进展,可能会移除这些值,并切换到更自由的构建方式。

此时,TileSideInMeters 并不是特别重要,可以暂时保留,直到有更合适的实现。对于计算其他值的地方,可能会进行一些清理工作,因为这些参数更多是游戏规格的一部分,可以根据需要调整。

通过这个清理过程,虽然原本计划是处理地面相关的内容,但也可以顺便进行一些整理工作,将项目朝着更合理的状态推进。最终,可能需要将这些参数设置成与游戏状态相关的值,以便更灵活地控制和调整。

在这里插入图片描述

引入 TypicalFloorHeight

在此过程中,TileDepthInMeters 将设置为典型的地板高度,这意味着会使用一个常见的值来表示地板的深度。通过这种方式,其他部分的代码可以使用此值进行初始化。在初始化世界时,将使用这个值来设置 chunk size,并确保它与世界的实际需求相匹配。

最终,TileDepthInMeters 被设置为一个合适的标准值,这样可以保证其他功能和计算能够顺利进行。
在这里插入图片描述

基于 MetersToPixels 设置 ChunkDimInMeters

为了确保 MetersToPixels 设置为 64 时,chunk size 和地面缓冲区高度能够协调工作,可以基于这一比例进行调整。通过将 chunk size 设置为与地面缓冲区高度一致,可以避免在像素计算过程中出现过多的分数值问题。具体来说,首先确定每个像素与米之间的比例,并确保 chunk size 和地面缓冲区的比例能够精确匹配,避免产生不必要的计算复杂性。

这种方式旨在使得像素和米之间的换算更加直接和简洁,避免了在处理这些值时需要进行复杂的浮动计算,从而提升了代码的稳定性和易维护性。
在这里插入图片描述

通过 GroundBuffer{Width,Height}TypicalFloorHeight 计算 WorldChunkDimInMeters

为了确定 WorldChunkDimInMeters 的大小,可以通过使用 MetersToPixels 的比例值和地面缓冲区宽度来进行计算。具体做法是,将 GroundBufferWidthPixelsToMeters 值相结合,得到适当的 chunk size。同样的方式也适用于地面缓冲区的高度,通过这种方式可以精确地确定物理预期。

对于地面高度,可以使用典型的楼层高度来设定,虽然这个高度最终如何处理可能还需要进一步调整,但在初步设计中,这样的处理方式是合理的。
在这里插入图片描述

设置 Tile{Side,Depth}InMeters

在当前的设计中,TileSideInMeters 主要用于确定楼梯的大小,尽管“tile”不再存在,依然可以保持该值不变,特别是在与世界构建相关的部分。TileDepthInMeters 被用作典型楼层高度的参考,而这些值主要用于世界构建中,因此应将其保留并避免在其他部分重复使用。其他不涉及的部分可以去除这些与楼层和瓦片相关的值,因为它们不再对其他内容产生影响。
在这里插入图片描述

以不同的方式计算 CameraBounds

在当前设计中,摄像机的边界应该以不同的方式处理,因为现在已经生成了正确的摄像机边界。摄像机的边界是基于屏幕高度和视图的实际大小(以米为单位)进行计算的,因此应确保摄像机边界与实际的米制视图保持一致。
在这里插入图片描述

根据 CameraBounds 引入 SimBounds

为了简化设计,计划将模拟区域(SimBounds)与摄像机边界(CameraBounds)一致,并在此基础上添加一定的扩展区域。这样,模拟区域的大小将与摄像机边界相同,只是多加了一个“围裙”区域(apron)。这个扩展区域的大小可以是固定的,比如每个方向上增加15米,具体的扩展量可以根据需要进行调整。
在这里插入图片描述

在这里插入图片描述

在游戏中查看结果

当前的设计仍然与之前相似,模拟区域的边界设置保持不变。唯一需要调整的是缩放级别,这样摄像机的像素与米的比例可能需要稍微调整,使其更接近以前的值。一个合适的选择是使用48作为每米的像素数,这更接近原置,或者试试42.238的比例,看是否更合适。尽管它不是2的幂次方,但考虑到渲染会进行缩放,使用这个比例应该没有问题。由于时间有限来的设,尽管在其他方面可能可以改进,但目前的调整已经接近完成。

这个我改MetersToPixels的值会段错误不知道为什么

请求绘制特定的 world_chunk

在处理矩形轮廓时,可以请求特定区域的地面数据。首先,检查地面缓冲区是否已存在所需的地面数据。如果已存在对应的缓冲区,则不需要额外处理;如果没有,则需要创建并填充新的地面缓冲区。通过比较当前位置与目标位置,确认是否已经获取到所需的地面缓冲区。如果未找到有效的缓冲区,则可以使用空缓冲区并填充数据。

此过程涉及查找和验证地面缓冲区,确保所需的地面数据正确加载。如果没有找到适用的缓冲区,则会通过创建一个新的缓冲区并填充数据来处理。最终,这将确保所有所需的地面数据得到有效管理,保证游戏世界的各个部分能够正确加载和显示。
在这里插入图片描述

代码运行出现断言错误

  1. 看看什么原因导致的段错误
    在这里插入图片描述

在这里插入图片描述

  1. GroundBuffer->P = NullPosition(); 函数NullPosition 的局部变量没初始化返回垃圾数据
    在这里插入图片描述

在这里插入图片描述

  1. 修改的代码
    在这里插入图片描述

  2. 运行结果
    在这里插入图片描述

在游戏中查看结果

系统在遍历所有的块时,几乎已经正确实现了,问题在于未能遍历到所有的块。具体来说,当直接访问某个块时,能够正确处理,但如果通过迭代,似乎有一个块遗漏了。这个问题比较难理解,属于一种不常见的 bug。虽然系统最终应该会用完所有块,但问题在于没有触发块的驱逐机制,因此即使块数量很大,程序依然没有达到预期的结尾。

虽然系统当前还没有触发驱逐,开发者对这个 bug 并不十分担心,预计可以推迟到明天来修复。问题本身表现得有些奇怪,尤其是在块的数量非常多的情况下,可能会影响程序的正常运行。然而,整体来看,缓存工作进行得还算顺利,只是遗漏的块让调试显得更为复杂。最终目标是实现一个有效的驱逐机制,并且大致能看到系统的正常工作流程。
在这里插入图片描述

在这里插入图片描述

找出 Chunk 为什么只有在角色踩上去时才会生成

系统遇到了一个问题,即无法生成预期中的某些块。虽然在循环中正确处理了从主块到最大块的范围,包括了最大块,并且这种处理方式在 x 和 y 轴上都没有问题,但仍然未能按预期填充所有块。这个问题表现得有点奇怪,难以理解为什么某些块没有被正确填充。可能是渲染方面出了问题,但这种可能性较小。

问题可能出在填充块的逻辑上,当前的处理方式可能并没有按预期正确填充块。系统的当前实现可能存在低效之处,导致无法及时发现错误。由于没有驱逐机制,系统需要更长的时间来完成这些操作,这也可能是导致问题的原因之一。虽然系统目前已经处理了一些块,但仍有遗漏,调试过程需要仔细检查每一步。

系统已经采用了相机边界和屏幕宽度的计算方式来映射块空间,获取最小和最大边界,这种方法看起来是合理的,但目前仍然没有完全解决问题,需要进一步调试并修复错误。

之前一切运行得都很完美

问题最终找到了根本原因:之前的绘制循环只会在块中存在数据时才进行绘制。也就是说,如果某个块中没有实体,就不会进行绘制,导致这些块在初始时并没有被渲染出来。然而,当玩家或敌人进入这些块时,实体被加载进来,块也变得活跃,从而触发了块的渲染。

这其实是一个相当简单的问题,只是没有意识到缺少数据时块不会被绘制出来。这个问题解决后,系统可以正常工作,块会在需要时激活和渲染。问题的本质是由于块中没有实体,因此这些块被跳过了,直到有实体进入后才会被渲染和处理。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

问题解决

虽然系统已经正常运行,但仍有一些问题需要处理,比如块的对齐、是否正确加载以及如何在不同的缩放级别下正常工作,这些细节还需要进一步改进。目前的实现还没有达到完美,但这些问题并不复杂,明天可以轻松解决。

接下来需要做的主要是无缝地生成块,这项工作其实并不困难。最终目标是将这部分操作放在单独的线程中,使其更加高效,从而避免现在出现的卡顿现象。总体来说,这种方案已经在初步实现上运行得相当顺利,而且没有涉及太复杂的操作,整体表现不错,令人满意。

问题:Muratori 语法是什么?

目前遇到的一个问题是图形中的一些透明区域没有完全填充,导致显示时仍然能够看到一些未完全渲染的部分。这可能是因为块的边界问题,也可能是由于某些渲染过程中的异常情况。这个问题看起来是由于块的边界处理引起的,可能涉及到特定的渲染或合成方式,具体原因还不太明确。

另外,还提到了一些过时的语法问题,特别是涉及到早期编译器的行为。在旧版本的编译器中,为了确保作用域正确,有时需要使用额外的括号来手动指定作用域范围。这是因为不同的编译器(如 MSVC 和 GCC)会以不同的方式处理作用域。在过去,为了让不同的编译器行为一致,必须使用这种额外的括号语法来避免作用域冲突。然而,随着编译器的改进,这种语法已经不再必要,但它在过去是确保代码正确性的唯一方法。

问题:随机地面斑块是否会基于某个种子,以便在 ground_buffer 被清除后可以按原样重新生成?

地面缓冲区是基于一些种子值生成随机的,这样即使在缓冲区被驱逐后,它也可以根据相同的种子重新生成,从而保持一致性。这个设计非常有用,因为它允许缓冲区根据其来源的块重新生成,确保了其可以无缝地恢复状态。

这种机制将会在明天进一步优化,以实现更加平滑的过程。这种基于种子值的生成方式不仅能够保证每次生成的内容一致,还能在需要时重新填充地面缓冲区,确保游戏世界的连贯性和流畅度。

问题:这个问题可能被问过很多次了,但有什么建议可以推荐学习哪种编程语言以及如何入门?

对于初学者来说,选择编程语言时最重要的是找到一个能够激发兴趣的语言,而不是直接选择像 C 或 C++ 这样的高级语言,因为这些语言对于完全没有编程经验的人来说可能太复杂。C 和 C++ 更适合在掌握了基础后,用于更精细的控制和高效代码编写。

对于初学者,建议选择一门简单、宽容且有良好标准库的语言,避免过早涉及复杂的编程技巧。像 Python 或者 JavaScript 这样的语言非常适合入门,它们允许用户轻松上手并快速看到成果,不需要过多关注底层细节。随着经验的积累,当掌握了编程的基础并准备好进一步提升时,再转向 C 语言等更具挑战性的语言,进一步掌握编程的高级概念和技术。

有人发现了一个 Muratori 风格的 for 语句

在调试过程中,发现了一段使用了 Muratori for 语法的代码,并且令人惊讶的是,它竟然在实际代码中出现了。之前并没有意识到还有人会使用这种语法。仔细查看后发现,这段代码只出现在某个特定的例程中,其他地方并没有类似的写法。虽然这段代码的风格与自己的代码有所不同,但确实在那个函数中出现了。这让人感到非常好奇,想知道是谁写了这段代码,或者这是否是对某个参考的引用。

问题:为什么在调用函数时不以地址的形式传递 World

在讨论中,提到为什么在调用函数时没有将 world 作为地址传递。对此,回答者表示他们确信已经在传递 world 的指针,并指出几乎每次调用时都会传递指针。并询问提问者在哪里看到了没有传递指针的情况。

问题:是否会实现 Z-buffer 和纹理缩放?

是否会使用混合 Z-buffer 缓冲区和纹理缩放。回答者表示不会使用 Z-buffer 缓冲区,因为它们不需要,并且使用它们会导致效率低下和质量下降。因此,将只进行排序操作,这样可以正确地进行 alpha 合成,而不需要使用简单的缓冲区。虽然有考虑过使用类似早期退出的方式来避免处理某些屏幕区域,但最终决定不使用。纹理缩放和旋转将会继续进行,但没有进一步的计划。

问题:是否有其他可能的 Z-buffer 方案?

在讨论 Z-buffer缓冲区的使用可能性时,提到如果进行非常昂贵的着色器计算,可能会尝试使用 Z 缓冲区来提前剔除不必要的计算,尤其是采用从前到后的绘制方式,以减少着色器计算量。然而,实际上即使是在这种情况下,也并不需要 Z 缓冲区,只需要一个二进制缓冲区,表示是否应该绘制。虽然有考虑过通过目标 alpha 来提前剔除,但最终认为即使如此,也不需要 Z 缓冲区,因为只要使用 alpha 就足以决定是否需要继续计算。

总体来看,这种做法不太符合需求,认为如果能通过目标 alpha 来决定是否剔除,完全不需要浪费带宽和计算去使用 Z 缓冲区。

是否可以通过屏幕尺寸或 CameraBoundsInMeters 来设置 SimBounds 的扩展?希望理解正确

如何设置SimBounds扩展的问题。SimBounds的目的是定义哪些内容需要高精度模拟,通常是屏幕上的物体以及周围一定距离内的内容,例如可能会发出声音或进入屏幕的角色,或者刚刚离开屏幕又可能返回的角色。目的是避免这些角色进入慢速更新循环,以确保它们能及时响应,保持与游戏玩法的紧密联系。

然而,对于SimBounds应设置为多少距离,仍然不确定。虽然可以根据屏幕尺寸或相机边界来设定,但具体的值还不清楚,可能需要更多的设计思路才能决定该设置什么。

问题:是否会实现动态光照或延迟渲染,以支持大量真实光源等?

讨论了动态光照和延迟渲染的问题。延迟渲染的一个问题是透明度处理效果不理想,需要额外的复杂操作才能使透明度正常工作。此外,对于一个2D游戏来说,现代GPU的计算能力非常强大,采用延迟渲染可能并不划算,因为它会牺牲透明度等其他功能,且只是在深度复杂度的管理上有所帮助。

延迟渲染的核心优势在于它可以减少计算量,尤其是在屏幕部分区域存在大量过度绘制时。它的作用是优化计算,避免对那些堆叠在一起的物体进行冗余计算。然而,在具体应用中,需要评估是否真的存在大量的堆叠问题,如果并没有,延迟渲染可能就不值得使用,反而会浪费时间且带来透明度等功能的限制。

问题:有没有可以推荐的硬核渲染工程师?

寻找硬核渲染专家的问题。提到如今这类专家不多,但可以考虑联系一些在显卡公司(如NVIDIA)或游戏引擎团队(例如Frostbite或Unreal引擎)的渲染人员。这样的专家可能会给出有关2D游戏是否使用深度缓冲的建议。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/894620.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python在线编辑器

from flask import Flask, render_template, request, jsonify import sys from io import StringIO import contextlib import subprocess import importlib import threading import time import ast import reapp Flask(__name__)RESTRICTED_PACKAGES {tkinter: 抱歉&…

力扣动态规划-20【算法学习day.114】

前言 ###我做这类文章一个重要的目的还是记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!! 习题 1.网格中的最小路径代价 题目链接…

从通讯工具到 AI 助理,AI手机如何发展?

随着AI进军各行各业,全面AI化时代已经到来。手机,作为现代人类的“数字器官”之一,更是首当其冲地融入了这一变革浪潮之中。 2024年年初,OPPO联合IDC发布了《AI手机白皮书》,公布OPPO已迈向AI手机这一全新阶段。到如今…

游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文

Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…

Qt常用控件 多元素控件

文章目录 1. QListWidget1.1 常用属性和方法1.2 常用信号1.4 例子1,操作元素 2. QTableWidget2.1 常用属性和方法2.2 常用信号2.3 例子1,创建表格3.1 常用属性和方法3.2 常用信号3.3 例子1,创建树形结构 Qt中提供的多元素控件有: QListWidget…

33.Word:国家中长期人才发展规划纲要【33】

目录 NO1.2样式​ NO3​ 图表 ​ NO4.5.6​ 开始→段落标记视图→导航窗格→检查有无遗漏 NO1.2样式 F12/另存为:Word.docx:考生文件夹样式的复制样式的修改 样式的应用(没有相似/超级多的情况下)——替换 [ ]通配符&#x…

Qt展厅播放器/多媒体播放器/中控播放器/帧同步播放器/硬解播放器/监控播放器

一、前言说明 音视频开发除了应用在安防监控、视频网站、各种流媒体app开发之外,还有一个小众的市场,那就是多媒体展厅场景,这个场景目前处于垄断地位的软件是HirenderS3,做的非常早而且非常全面,都是通用的需求&…

【零拷贝】

目录 一:了解IO基础概念 二:数据流动的层次结构 三:零拷贝 1.传统IO文件读写 2.mmap 零拷贝技术 3.sendFile 零拷贝技术 一:了解IO基础概念 理解CPU拷贝和DMA拷贝 ​ 我们知道,操作系统对于内存空间&…

全栈开发:使用.NET Core WebAPI构建前后端分离的核心技巧(一)

目录 cors解决跨域 依赖注入使用 分层服务注册 缓存方法使用 内存缓存使用 缓存过期清理 缓存存在问题 分布式的缓存 cors解决跨域 前后端分离已经成为一种越来越流行的架构模式,由于跨域资源共享(cors)是浏览器的一种安全机制,它会阻止前端应用…

《Linux服务与安全管理》| 数据库服务器安装和配置

《Linux服务与安全管理》| 数据库服务器安装和配置 目录 《Linux服务与安全管理》| 数据库服务器安装和配置 任务一: 安装PostgreSQL数据库,设置远程登录,客户端可以成功登录并操作数据库。 任务二: 安装MySQL数据库&#xf…

Linux系统之whereis命令的基本使用

Linux系统之whereis命令的基本使用 一、whereis命令介绍二、whereis命令的使用帮助2.1 whereis命令的帮助信息2.2 whereis命令帮助解释 三、whereis命令的基本使用3.1 查找命令的位置3.2 仅查找二进制文件3.3 仅查找手册页3.4 输出实际使用的查找路径3.5 指定自定义搜索路径 四…

Autosar-以太网是怎么运行的?(Davinci配置部分)

写在前面: 入行一段时间了,基于个人理解整理一些东西,如有错误,欢迎各位大佬评论区指正!!! 目录 1.Autosar ETH通讯软件架构 2.Ethernet MCAL配置 2.1配置对应Pin属性 2.2配置TXD引脚 2.3配…

【Block总结】CSAM,包含分割、关键点、切分等均适用!|即插即用

论文信息 标题: CSAM: A 2.5D Cross-Slice Attention Module for Anisotropic Volumetric Medical Image Segmentation 论文链接: https://arxiv.org/pdf/2311.04942 GitHub链接: https://github.com/aL3x-O-o-Hung/CSAM 创新点 CSAM(跨切片注意力模块&#xff…

解决PyG安装中torch-sparse安装失败问题:详细指南

1 问题描述 最近在学习GNN,需要使用PyTorch Geometric(PyG)库。在安装PyG的过程中,遇到了torch-sparse安装失败的问题,错误提示为: ERROR: Failed building wheel for torch-sparse本文将详细记录问题的解…

鸟哥Linux私房菜笔记(三)

鸟哥Linux私房菜笔记(三) 该第三部分和第四部分主要为原书的第十一章(正则表达式与文件格式化处理),第十二章学习shell脚本,第十六章(进程管理与SElinux初探部分),第十七…

python学opencv|读取图像(五十四)使用cv2.blur()函数实现图像像素均值处理

【1】引言 前序学习进程中,对图像的操作均基于各个像素点上的BGR值不同而展开。 对于彩色图像,每个像素点上的BGR值为三个整数,因为是三通道图像;对于灰度图像,各个像素上的BGR值是一个整数,因为这是单通…

Spring Boot 2 快速教程:WebFlux处理流程(五)

WebFlux请求处理流程 下面是spring mvc的请求处理流程 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找) 匹配条件包括…

小程序设计和开发:如何研究同类型小程序的优点和不足。

一、确定研究目标和范围 明确研究目的 在开始研究同类型小程序之前,首先需要明确研究的目的。是为了改进自己的小程序设计和开发,还是为了了解市场趋势和用户需求?不同的研究目的会影响研究的方法和重点。例如,如果研究目的是为了…

Vue3.0实战:大数据平台可视化(附完整项目源码)

文章目录 创建vue3.0项目项目初始化项目分辨率响应式设置项目顶部信息条创建页面主体创建全局引入echarts和axios后台接口创建express销售总量图实现完整项目下载项目任何问题都可在评论区,或者直接私信即可。 创建vue3.0项目 创建项目: vue create vueecharts选择第三项:…

Java自定义IO密集型和CPU密集型线程池

文章目录 前言线程池各类场景描述常见场景案例设计思路公共类自定义工厂类-MyThreadFactory自定义拒绝策略-RejectedExecutionHandlerFactory自定义阻塞队列-TaskQueue(实现 核心线程->最大线程数->队列) 场景1:CPU密集型场景思路&…