游戏引擎学习第87天

当直接使用内存时,可能会发生一些奇怪的事情

在直接操作内存时,一些意外的情况可能会发生。由于内存实际上只是一个大块的空间,开发者可以完全控制它,而不像高级语言那样必须遵守许多规则,因此很容易发生错误。在一个具体的例子中,本应使用临时存储的内存区域,但错误地使用了存储大小作为内存指针,尽管这种做法本应导致崩溃,却意外地没有崩溃。

这个错误之所以没有导致崩溃,是因为临时存储大小恰好是一个合法的内存边界(比如1GB),因此它指向了一个合法的内存区域。即使实际的存储内存与这个内存边界并不匹配,系统依然允许访问这个内存区域,尽管这实际上是错误的做法。由于该内存区域之前没有被分配任何数据,所以程序可以正常写入并执行,这就造成了一个"幸运"的情况,尽管这种错误本应导致崩溃。

这种情况展示了内存管理中的潜在风险,因为错误的类型转换可能会导致不可预料的结果。在实际的代码中,应该使用正确的指针进行内存初始化,而不是错误地使用存储大小作为指针。尽管这次错误没有立即引发崩溃,但实际上它是一个严重的错误,应该及时修正。

回到我们之前的工作,即制作无缝地面瓷砖

在继续进行地面纹理的处理时,首先需要将现有的纹理从带有接缝的状态转换为无缝的状态,以确保它们与相邻的区域始终对齐,不显示边界上的接缝或伪影。虽然看起来这可能有些复杂,但由于架构的设计,这个过程实际上并不难。

接下来,还需要解决另一个问题,这个问题相对更具挑战性,即如何处理性能问题,特别是如何让纹理生成在后台进行,而不会影响前台的性能。这个问题暂时不会处理,重点是继续优化和调整。

在纹理缓存方面,目前缓存中的地面纹理不会被清除,导致当缓存中的纹理用尽时,系统就没有足够的纹理来填充。这就需要实现一个机制来清除不再需要的旧纹理,以腾出空间来生成新的纹理。

这个清除旧纹理并生成新纹理的机制是接下来的任务,它涉及到设计一个有效的"驱逐"策略来管理纹理缓存的内容,确保系统在缓存用尽时能自动回收并生成新的纹理。

Blackboard: 如何制作无缝瓷砖

首先,目标是使地面纹理无缝拼接。目前我们正在将软边缘的纹理"撒入"到瓷砖中,通过这种方法产生漂亮的地面纹理,但问题在于,这些纹理被撒入时没有考虑到硬边界的限制。因此,目标是将纹理的接缝处理为无缝,使得所有相邻的瓷砖之间的纹理能够对齐。

为了解决这个问题,可以采取的方式是将整个3x3区域的纹理撒入,最终只提取中间部分。这样做的前提是保证每个瓷砖的纹理与其周围的瓷砖一致,确保纹理能够顺畅地拼接。这种方法有效的原因在于,如果我们确保每个瓷砖的处理顺序一致,就能保证所有的重叠部分一致,从而实现无缝拼接。

此外,由于现有的位图代码已经处理了裁剪,我们无需做额外的处理,只需设置裁剪区域,进行纹理撒入。裁剪会提前剔除不需要的部分,避免浪费内存和计算资源。因此,在优化之前,现有的裁剪机制就已经能为实现无缝拼接提供一定的性能提升。

遍历3 * 3网格中的瓷砖

为了修复无缝拼接的地面纹理,计划的做法是对现有的处理方法进行修改。具体而言,目标是使用3x3区域来进行纹理撒入,而不只是填充中间的部分。为了实现这一点,需要使用一个随机种子,并结合当前的块坐标(chunkX 和 chunkY)来生成新的合成坐标。尽管目前不涉及Z轴处理,Z轴的坐标将始终保持不变,因为当前的工作不需要在三维纹理中处理Z轴的无缝拼接。

对于X轴和Y轴,将循环遍历每个块,从当前的块坐标出发,首先往回一步,再向前一步。这样就能覆盖一个3x3的区域,确保邻近区域的纹理能够无缝衔接。在执行这些操作时,选择的循环顺序并不重要,只要保持一致性,就能实现无缝拼接。

接下来,继续使用现有的绘制循环来完成纹理的撒入,只不过这次是覆盖整个3x3的区域,而不仅仅是中心部分。最终的任务是确保中心位置能够准确反映不同块之间的关系,从而保证纹理的无缝连接。

确保中心正确反映出我们处于不同的区域

为了计算中心点并进行无缝拼接,决定修改循环结构,采用动态计算的方式来处理块的偏移量。具体来说,循环的偏移量从 -1 到 1,将每次偏移与当前的块坐标(chunkX 和 chunkY)结合。这使得可以在每次迭代中动态计算新的块坐标,从而生成正确的纹理区域。

通过这种方式,可以确保在X和Y方向上处理所有9个区域(包括 -1、0 和 1)。此外,还可以根据需要将Z坐标添加到计算中,尽管目前Z轴的处理并不影响无缝拼接。

在计算这些块坐标后,接下来需要确定纹理图像的中心点。具体而言,需要考虑如何准确地计算位图的实际中心,以确保在纹理的生成过程中无缝拼接得以实现。

Blackboard: 中心的考虑

在之前的实现中,使用了位图中心来决定纹理的绘制位置,从中心点开始向外扩展。但是,随着每个纹理块的独立处理,实际上每个块的"中心"并不再是固定的,而是每个块自己相对于周围区域的中心。因此,需要重新计算每个区域的中心点,以便在每个独立的纹理块上正确地进行操作,而不是直接使用原始的位图中心。这种变化使得每个纹理块的处理更加灵活,能够适应无缝拼接的需求。

改变中心的含义

为了实现无缝拼接,需要调整计算中心点的方式。原本的中心点是固定的,但现在每个纹理块的中心点应该是该块的相对中心。因此,需要根据每个块的位置调整中心点,即从原来的中心点减去一个偏移量,然后根据偏移量来确定新的中心点位置。这一过程通过调整每个块的宽度和高度,并根据每个块的具体位置来调整随机种子的值,从而保证每次生成的纹理块使用相同的随机偏移量,确保纹理块间的无缝拼接。

在游戏中查看结果并检查代码

在检查生成的纹理时,发现它们并不无缝,仍然存在一些问题。分析后,发现问题出在随机种子的计算上,尽管应该使用基于块的绝对索引来生成一个固定的随机种子,但是生成的中心点还是存在偏差。

具体来说,中心点的计算方法应该是:从纹理的顶部开始,减去一半的宽度和高度,之后根据当前块的偏移量调整。然而,原先的偏移量计算有误,导致了纹理拼接不准确,产生了接缝问题。

修正计算

发现之前的计算有误,问题在于块的偏移量应该是从-1、0到+1,而不是从0、1、2开始。因此,中心点的计算需要根据正确的偏移范围进行调整。原本的计算错误导致了不正确的移动,无法正确定位到左上角和右下角。

调整后,从中心点开始的计算将正确地将纹理从左上角移动到右下角,解决了之前的问题。

看看我们目前的进展

当前的情况还是没有解决问题,纹理的对齐看起来仍然偏差较大,说明存在较为严重的逻辑错误。由于目前还没有完善的调试工具,问题只能通过直觉来推测,虽然问题不应太难解决。需要进一步检查和调整,确保各部分正确对齐并符合预期。

再看一遍,看看有什么不同

发现了一个问题,原本的代码中有一部分没有被使用,导致计算出错。需要将相关部分重新启用,以确保计算的正确性。这个问题非常明显,应该能够通过调整来解决。

因为我们忘记使用新的中心了

意识到之前的错误,修改代码时没有仔细检查,导致了计算问题。原本应该使用上角点进行偏移计算,而不是直接应用宽度和高度的随机值。这提醒了在修改代码之前,要先确认每一部分的作用,避免不必要的错误。

我们现在在X轴上是无缝的,但Y轴上不是

目前在X轴方向已经实现无缝对接,但Y轴方向仍然存在问题。看起来是Y轴的计算出现了错误,可能是因为Y轴方向的偏移处理存在反转或者其他计算上的问题,导致没有正确对接。

我的X Y轴都有问题

代码的ChunkX,ChunkY,ChunkZ 好像没使用

忘记使用ChunkX,ChunkY,ChunkZ

关闭草丛,看看我们在Y轴上的处理有何不同

在检查Y轴的计算时,发现bitmap的中心和偏移量计算是正确的,应该能够正确绘制。然而,问题依然存在,可能是因为Y轴的某些计算方式不对,或者存在其他未发现的逻辑问题。为了更简单地调试,已将某些元素从计算中移除,但Y轴的计算仍然没有解决。

考虑一下这个问题,尝试交换X和Y,看看哪个是主要轴

在调试时,交换X轴和Y轴的计算顺序,发现问题并不在于计算顺序或重叠问题,而是在Y轴的处理方式上。因此,可以确认问题出在Y轴的处理逻辑上,需要重新审视Y轴的计算方法。

我们的Y轴处理出了什么问题?

关于Y轴的处理方式似乎没有问题。当进行"ChunkY"操作时,看起来是正确的。同时,涉及到宽度和高度的部分也显示为正确。不过,需要考虑一些细节,尤其是在高度的计算上,虽然目前看起来是正确的。

我们的边缘可能顺序错了

由于地面块的填充方式与坐标系统的翻转有关,导致堆叠顺序出现问题。猜测可能是由于边界对齐的顺序错误,具体来说,顶部和底部的边界可能被颠倒了,因为方向处理不当。

检查一下是否是这种情况(在游戏中)

检查后发现,问题确实是由于Y轴翻转导致的,需要始终考虑到这一点。现在,地面纹理已经可以无限平铺,虽然纹理本身并不是特别理想,因为在合成过程中没有做过多优化,但目前的效果已经不错。为了使效果更加直接,考虑将纹理固定为某一种类型,比如草地或石头,这样效果会更好。

尝试了将纹理类型统一后,发现效果提升了不少,尽管在某些地方,像是某些接缝处,可能会有一些伪影,看起来有些奇怪,这可能是因为某些细节问题。不过,整体效果已经相当不错了,随着更多纹理的加入,以及将区域划分为不同类型(如草地、石头等),效果将更加完善。这些是未来需要进一步实现的功能。

恢复草丛

决定将纹理切换回草地并重新添加毛球,同时确保毛球没有重叠问题,并计划暂时停止改进这一部分。这个系统可以在未来逐步扩展。观察到纹理中的毛球看起来有些集中,可能是因为当前使用的随机数生成器在生成过程中出现了问题,导致了随机性不足,进而出现了明显的规律性。

虽然不认为这会是一个严重问题,但可以看到随机数生成器的漏洞。如果问题确实与随机数生成器有关,那么可能需要进一步调整。此外,另一个潜在问题是如果精灵周围有透明区域,也可能导致这种效果。

显示缓冲太小改大一点

给它一些松动空间

考虑到可能出现的问题,决定为毛球添加一些"松散"参数,以检查是否能够解决集中现象。虽然一开始认为毛球之间需要有一定的接触,但在使用中心点后,意识到这种方式并不完全适用。因此,推测问题可能与随机数生成器有关,考虑在未来使用更高质量的随机数生成器。

目前,认为系统已经处于良好状态,整体效果可以接受,因此决定开始处理下一个问题。不过,决定在开始之前先解决一些其他小问题,确保继续推进。

恢复打开石头绘制

强制我们进入一个很快就会没有瓷砖的情况

为了更快速地看到问题的发生,决定通过调整瓦片数量来加速这一过程。之前需要走很长一段路才能看到瓦片用完的情况,因此现在通过减少瓦片的数量,使得在短时间内就能观察到瓦片耗尽的情况,从而验证驱逐机制是否正常工作。

调整了瓦片数量后,虽然最初的猜测并不完全准确,但通过进一步减少瓦片数量到16个,终于实现了快速耗尽瓦片的效果。接下来,目标是确保能够通过重复使用旧的瓦片来填补空缺。

通过重用旧瓷砖来填充每个空的缓冲区

首先,现有的循环已经能够进行地面块填充,但问题在于目前没有有效的方式在预分配的16个缓冲区填满后获取更多的空缓冲区。因此,目标是找到一种方法,能够确定目前存在的16个块中,哪个最不重要,最适合被替换。

考虑到目前的情况,虽然有多种解决方案,但由于还处于初期阶段,决定暂时不使用过于复杂的策略(比如LRU算法),而是采用一种简单且直接的方法,即遍历整个缓冲区。虽然这种方法效率较低,但可能是目前最合适的选择,避免过早引入复杂的机制。

保留最远离相机的区域

在这个过程中,目标是通过遍历缓冲区来确定哪个地面块最远离相机,从而决定替换哪个块。通过计算每个块相对于相机的位置,使用相对位置的平方长度来衡量与相机的距离。对于每个地面块,只考虑其XY平面的位置,而不关心高度。

为了实现这一点,首先需要检查缓冲区是否有效。如果缓冲区从未被使用过,那它将成为最佳选择,因为它是空的,最适合替换。接着,初始化一个变量来存储最远的缓冲区,最初设定为一个非常大的值(比如最大值),确保该值不会被遗漏。

虽然这种方法有点昂贵,但目前并不关心性能,更多的是确保功能正常运作。一旦性能优化变得更为关键时,可以考虑通过存储上次计算的结果来减少计算量。

引入Real32Maximum

决定使用平台定义的最大浮动值(real32)来初始化最远缓冲区的距离。这个最大值是在limits.h头文件中由C编译器定义的,具体值取决于当前编译平台。当然,如果需要的话,也可以手动定义这个最大值,因为它是32位浮动数值。

通过将最远距离初始化为最大值,可以确保在选择替换缓冲区时,如果没有已经选中的缓冲区,就会优先选取一个新的缓冲区。这种方式保证了即使没有其他缓冲区,依然能够正确地做出选择。

找到最适合替换的缓冲区

在这段代码中,首先设置了最远缓冲区的初始值为最大浮动值(real32),确保没有任何缓冲区会优先被选中。然后,通过计算每个地面块的相对距离,比较它们与当前最远缓冲区的距离,选择距离相机最远的缓冲区进行替换。

这个方法是非常基础的,属于暴力破解式的实现,遍历所有16个地面缓冲区,每次都进行比较。尽管这种方式非常低效,但由于目前还不关心性能,所以决定暂时使用它。未来在引擎优化时,会考虑重新设计替换逻辑,以避免过早进行性能优化,毕竟现在的实现方式可能会随着需求变化而被改进。

编译并查看代码

在这段代码中,首先初始化最远缓冲区的距离为零,意味着任何缓冲区都将被认为比这个初始值更远。然后,通过遍历所有地面缓冲区,检查每个缓冲区是否与当前绘制的区域相同。如果是相同的区域,就跳过该缓冲区,因为不需要填充它。如果是不同的区域,就计算该缓冲区与相机的距离,并与当前已找到的最远缓冲区进行比较。如果该缓冲区更远,就更新最远缓冲区。

如果缓冲区无效(没有内容),则选择该缓冲区进行填充,因为我们不希望填充已经有内容的缓冲区。最终,通过这种方式确保填充最适合的缓冲区,同时避免不必要的填充。

看起来16个地面缓冲区太少了

目前的填充系统看起来已经基本正常,之前设置的16个缓冲区显然太少,导致地面区域填充不足,修改为32个缓冲区后效果有所改善,可以持续走动而不会耗尽地面。然而,可能需要进一步优化绘制的范围边界,以避免溢出。

在当前的实现上,暂时不打算增加更复杂的地面元素如草地或石块的生成,因为这些更像是与世界生成相关的内容,可能会在之后的开发阶段处理。总的来说,系统已经取得了较好的进展,接下来可以考虑进入新的开发任务。

最后处理细节图层

发现了一个问题,地面上的某些区域被覆盖了,这主要是由于有两个地面层的缘故,导致细节层的内容被地面层覆盖。为了解决这个问题,可以将地面处理分成两次迭代,先处理底层地面,再处理细节层的地面,这样就能够避免覆盖问题。

通过这种方式,可以确保细节层总是位于底层地面之上。调整之后,重新测试时,发现问题已解决,效果变得更加理想。虽然这个解决方案目前有效,但以后可能需要进一步优化地面合成器,使其更智能,处理更多复杂情况。不过,这个方法足以解决当前的问题。

接下来该做什么?

可以考虑开始处理地面块的多层Z轴支持。这是一个值得着手的方向,而且也能为明天的工作做好铺垫。

另外,还可以尝试实现一个功能,在代码重新加载时自动更新。通过在Win32层实现代码重新加载时,增加一个智能检测机制,能够在代码重新加载后自动触发重新生成的操作,这样可以提高开发效率,避免手动干预。

让代码重新加载时告诉我们何时加载完成

在Win32层,可以加入一个变量来标记可执行文件是否已经重新加载。当通过游戏内存传递数据时,可以引入一个类似于"executable reloaded"的标志。这会帮助在调试过程中执行特定的操作,例如清空缓存。

具体做法是:当检测到可执行文件已经重新加载时,通过该标志来清空相关缓存。这样做能够确保在重新加载后,缓存中的内容被重置,以便进行新的操作。

实现时,可以在Win32的代码加载部分检查是否执行了重新加载,如果是,就将该标志设置为true,表示重新加载了可执行文件。如果没有重新加载,则保持为false。这样,简单的标志机制能够帮助在特定情况下执行清理操作。

测试新改进的实时代码编辑

通过启用即时代码编辑,可以在修改地面渲染逻辑时立即查看效果。例如,当关闭草地渲染(即不再显示草地丛)的功能时,修改后的效果会立即生效,不需要重新编译。这种即时反馈使得调整和实验变得更加高效,尤其在调试和优化时,可以节省大量的时间。即时代码编辑不仅提高了开发效率,而且使得开发过程更加有趣,即使只是为了体验这种不需要等待编译结果的乐趣。

有些担心我们绘制的内容太多了...

在调试时,怀疑绘制的区域过多,因此决定进一步调查为什么16个缓冲区不够用。通过修改绘制矩形的调用,尤其是绘制矩形轮廓的部分,尝试找出绘制过多区域的原因。这有助于更精确地控制绘制区域,避免不必要的绘制工作,进而优化性能。

调整代码

为了调试,将绘制缓冲区的操作提前到上方,这样可以直接查看调试区域。尽管这个顺序不符合理想的逻辑(因为通常填充和绘制应该分开),但由于绘制操作会在一个独立的线程中执行,所以不需要过多关注顺序上的细节。这一改变有助于更好地观察调试信息。

计算屏幕上能容纳多少个地面缓冲区

通过调试,发现16个块实际上不足以覆盖所有显示区域,尽管32个可能过多,16个的数量确实不够。调整后,边界显示清晰,结果令人满意。

评估我们当前的情况

在完成当前的调整后,整体状态非常良好,下一步将开始处理与RZ层相关的问题,可能会在明天进行。虽然需要继续观察内存占用和地面块的大小是否合适,但目前的工作进展顺利。最终,决定暂时注释掉一些代码,以便需要时重新启用。整体来说,地面纹理现在运行正常,达到了预期效果

随机生成的地板瓷砖已经缓存了吗?

它们已经被缓存了

你认为像使用static_cast来增加更多检查(例如从int到指针的转换)相比标准的C风格转换有用吗?它不会忽略所有类型检查吗?如果使用static_cast,难道不是一开始就能发现那个bug吗?

在讨论是否使用 static_cast 来增加类型检查时,提到需要权衡在代码中加入新特性的价值。虽然 static_cast 比 C 风格的类型转换更严格,但并不是所有情况下都值得引入更多检查。尤其是在考虑到未来语言变化的情况下,比如 C++ 可能会逐渐被淘汰,可能会转向某种包含 C 特性的语言,但不再包含 C++ 的复杂性,因此尽量避免在代码中加入不必要的 C++ 特性可能是明智的。

关于引入更多检查的实际意义,强调了应该只在频繁出现且难以调试的错误上增加防护。如果某个问题很少出现且不容易调试,就不需要花费过多时间去处理。实际工作中,不应花费过多时间去防范不常见的错误,因为这可能只是浪费时间。比如,遇到一个流中的 bug,虽然出现过一次,但不代表需要专门添加检查,只要这类错误不频繁发生,就不必专门做防范。

如果遇到的错误变得频繁或影响开发效率,那么增加检查措施就变得更有意义。

你认为这种团块感实际上是由于从区块中心的喷洒距离造成的吗?

在讨论草丛的聚集性时,最初怀疑是由于草的分布受到了随机数表的影响。为了解决这一问题,可以通过使用 C 的随机数生成器来进行检查,尽管 C 的随机数生成器本身并不完美,但它不会遇到随机数表的问题。通过调整参数,可以观察草丛的分布,发现并不如预期的那样聚集。后来,发现问题其实是因为在之前的实现中,草的绘制没有执行第二次渲染,从而导致相邻的对象覆盖了草的部分区域,而不是随机数本身的问题。

修复了这个渲染问题后,草的分布看起来更自然了,尽管随机数表依然不完美,但问题并不出在这里。最终决定回到一个合适的草的数量,而草通常应该只出现在草地上,这部分的细节可以稍后再处理。

你知道为什么有时树木会晃动吗?

当前游戏没有真正的渲染器,只使用了一个简单的位图渲染调用,这导致屏幕上出现了一些视觉伪影。这些伪影的出现是因为没有进行物体的排序处理,物体的显示顺序取决于它们被处理的顺序,因此可能会出现物体穿透其他物体的情况。另一种问题是物体的位置没有进行子像素精度处理,物体的坐标是浮动的,但会被强制四舍五入到整数坐标。这样,物体在移动时会出现轻微的抖动,尤其是在物体的两个坐标分别进位到下一个整数时,彼此之间的距离会发生变化。这些问题在未来的渲染器中会得到解决,渲染器会支持子像素精度,从而使运动更加平滑,特别是在处理缓慢移动的物体时,这也会改善游戏的视觉效果。

是什么导致了延迟?

当前的延迟问题有两个主要原因。第一个原因是背景块的生成没有在独立的线程中进行,而是在需要的时候同步生成,这个操作非常耗费资源,因此导致了延迟。如果将这些操作放到独立线程中,处理就不会影响帧率。然而,即便如此,这个操作本身的开销不足以造成明显的帧率影响。真正导致显著延迟的原因是,目前生成地面块时使用了非常慢的位图填充过程,这是将位图渲染到屏幕上最低效的方式,且此过程中没有进行任何优化。除此之外,编译模式也没有启用发布模式(Release Mode),如果切换到发布模式,程序性能将有所提升,延迟会减小。例如,在构建过程中通过调整编译选项来进行代码优化,就可以明显减少延迟,让卡顿时间变短。总之,这些延迟主要是因为没有进行足够的代码优化所导致的。

现在地面瓷砖中还会看到背景颜色透过吗?

目前,背景颜色透过地面瓦片的情况应该已经不再出现,但还没有做完全的检查来确保这一点。问题更多地与地面瓦片的生成方式有关。为了更容易地检查这个问题,可以使用一种明显的颜色(如鲜艳的粉红色)作为临时标记,虽然这不是一种完美的检查方法,但它能帮助更清楚地看到问题区域。通过这种方式,可以确定是否还有背景透过地面瓦片显示出来。尽管如此,也能发现当瓦片尚未完全填充时,它们在屏幕上出现时会闪烁。未来可能需要进一步优化,做出预测,提前加载尚未显示的瓦片,以避免类似问题的发生。

这个区块代码已经准备好添加地面上的洞了吗?

当前的地面块生成代码已经为添加地面上的洞洞做好了准备,可以创建任意大小的洞。实现这个功能只需要修改绘制位图的代码,通过调整 Alpha 通道的值来切割出洞。具体来说,使用一个填充透明度(Alpha)的位图方法,如果将源 Alpha 通道的值反转,并与目标 Alpha 通道相乘,就能有效地减少源图像的透明度,从而实现打洞效果。这是一种非常简单的方式,可以根据需要生成不同形状的洞并穿透显示下面的内容。

通过这种方法,可以在地面块中轻松地添加洞洞,并看到透明区域,原本绘制的背景颜色(如粉红色)会在洞中显示出来。实现这一功能时,创建洞的过程并不复杂,只需用一个指定形状的位图来"打洞"。

你能否编写代码以确保特定的帧率,但利用额外的空闲时间在后台生成地面纹理,可能先生成低质量版本以避免没有纹理?

可以编写代码来保证特定的帧率,同时利用多余的时间在后台生成地面纹理,甚至可以生成低质量的版本以避免完全没有纹理。实现这一目标有两个方面:低质量与高质量纹理的生成,以及帧率的保证。现代处理器,尤其是像树莓派这样的四核处理器,要求有效利用多核处理能力。把这些任务放在主循环中进行帧率限制并不是最优选择。为了充分利用处理器的多核,通常需要将任务分配给多个线程处理,这样可以利用空闲的 CPU 时间。通过这种方式,能够更高效地进行后台操作,而不是简单地通过主循环来限制帧率。

回顾,展望未来并结束语

游戏的开发进展顺利,目前已经完成了一部分地面纹理的生成,并且实现了可以处理任意数量Z层的功能,允许在多个层次上生成地面纹理。这个新系统支持缓存任何位置的瓦片,增加了灵活性。在未来的工作中,计划开始进行最终的Z层处理,尤其是实现房间之间的视角关系,让上层房间能够俯视下层房间。这项工作会需要一定的时间和精力,但这是开发过程中重要的一步。

接下来,计划继续进行图形优化和功能完善,确保开发的各个模块能够顺利协同工作。之后还将继续完善地面纹理和Z层的交互效果。

相关推荐
爱看大明王朝15665 小时前
磁件学习-磁性元器件的极限计算
笔记·学习
东风破1375 小时前
DM8达梦共享存储集群DSC搭建步骤
数据库·学习·dm达梦数据库
星幻元宇VR6 小时前
VR科普大空间:沉浸式公共教育新模式
科技·学习·安全·vr·虚拟现实
tohand7 小时前
Unity 完美假阴影实现文档
unity·游戏引擎
笨鸟先飞的橘猫8 小时前
MMO游戏中的“跨服团队副本”匹配与状态同步系统
分布式·学习·游戏·lua·skynet
雨落在了我的手上9 小时前
如何学习java?
java·开发语言·学习
吃好睡好便好10 小时前
汽车基本组成
学习·汽车
nnsix10 小时前
Unity 动画 Avatar 笔记
笔记·unity·游戏引擎
拾忆丶夜11 小时前
unity 热力图学习
学习·unity·游戏引擎
red_redemption11 小时前
自由学习记录(183)
学习·ue项目改名字的学问