游戏引擎学习第77天

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

回顾昨天的 bug

今天我们继续开发进度,进行调试昨天代码的问题,主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏,但我们希望能够处理多层的房间,玩家可以上下走动,这需要处理与三维位置相关的问题。

昨天我们开始调整实体的 Z 坐标,确保它们有完整的高度信息,并且应该从地面开始,位置会从地面向上延伸。然而,在调试时,发现玩家的角色似乎比预期低,应该碰到树木的位置时,角色却没有停下来,显得像是角色下沉了。我们也观察到角色在楼梯处的碰撞没有按预期进行,可能是因为角色的 Z 坐标没有正确计算其高度。

因此,有人猜测问题出在没有修正站在地面上的代码,忘记考虑实体的高度。也就是说,虽然角色的底部位置被设置在地面上,但角色的高度应该从该位置向上浮动。因此,调整这个问题,确保角色位置正确是接下来的重点。

黑板:实体的基点与地面位置之间的差异

有人提出了一个很好的猜测,问题可能出在实体的位置计算上。我们来看一下实体的高度问题。假设实体是这样的形状(侧面图),它的 Z 维度代表它的高度。如果我们把实体的高度表示为 Z 维度,那么它的中心位置应该在地面上方半个 Z 维度的高度。也就是说,实体的实际地面接触点应该是它的中心位置减去它的一半高度。

因此,假设地面是某个高度,那么实体应该从地面加上它的高度一半来确定其实际的位置。这就意味着,我们不能简单地把实体的位置设置为地面,而是要加上它的一半高度,才能确保它的底部位置正确。换句话说,地面实际上应该在中心点下方半个 Z 维度的位置。

这个建议看起来很有道理,可能正是导致问题的根本原因。

查看当前如何指定这些概念

在处理这个问题时,首先发现了实体的位置计算没有考虑到实体的尺寸,尤其是高度(Z 维度)。具体来说,地面高度的计算没有考虑到实体的高度,这导致了实体的位置不正确。

我们在处理重叠(overlap)时,地面高度是通过一个插值(lerp)计算得出的。为了修复这个问题,计划在进行重叠测试后,根据实体的尺寸调整地面高度。也就是说,在计算出重叠后的地面高度后,需要再调整它,使其考虑到实体的实际尺寸,特别是其高度(Z 维度)。这应该能解决当前问题,确保实体的底部能正确地与地面对齐。

game_sim_region.cpp: 将 0.5 * Entity->Dim.Z 加到地面位置

要解决这个问题,计划将地面高度调整为原本的地面高度加上实体高度的一半。也就是说,在计算地面高度时,需要将原本的地面位置上移,移动的距离是实体高度的一半。这就是在之前图示中提到的做法,通过这种方式确保实体的位置正确。
在这里插入图片描述

运行游戏,发现问题还没完全解决

调试过程发现当前的碰撞行为有些不合理,看起来可能是已经到了顶部楼层,导致上下碰撞变得异常。此时需要进一步调试碰撞检测代码,尤其是在绘制方面。为了更清楚地理解问题,首先可能需要添加一些调试代码来检查当前的碰撞情况,确保问题出在哪里。

调试:进入计算地面位置的代码

通过调试代码,发现碰撞系统中的地面计算已经修复了之前的错误,角色的位置现在正确地悬浮在地面上,符合预期的高度(0.62的实体高度的一半)。这解决了之前在预演阶段提到的bug。不过,问题可能还在于绘制部分的代码没有完全处理好,因此需要继续修复绘制代码。

game.cpp: 查看当前的绘制代码

绘制代码当前使用了一个占位符方法,导致调试变得有些困难。具体来说,在绘制位图时,传入的是位图的左上角位置,而不是位图的中心。因此,绘制代码中的 DrawBitMap 调用使用了最小角落位置,而这与预期的中心对齐有所不同。代码实际上对位图的位置进行了偏移,但并未考虑位图的实际大小,导致绘制时的对齐问题。虽然目前的代码中已经通过偏移量修正了这个问题,但这种方式比较粗糙,存在不一致的问题。最终需要决定是修复这个对齐bug,还是重新整理代码来改善渲染系统。在不确定时,决定暂时不对渲染系统做大幅改动,保持现有代码结构。

引入 EntityBaseP

为了正确对齐实体的绘制位置,应该将实体的位置调整为基于地面对齐,而不是基于其中心位置。建议将实体的当前位置重新命名为 EntityBaseP,其位置应为当前实体位置加上实体在 Z 轴上的一半尺寸。这样,绘制时就能够与地面对齐,因为当前地面位置的对齐是基于这个偏移量的。虽然目前这种方式对大多数实体来说是合理的,可能对于飞行类实体不适用,但这可以作为初步解决方案,未来如果需要,可以进一步引入自定义对齐方式。

此外,绘制影像时的透明度计算(ShadowAlpha)也应与此对齐,以确保绘制的一致性,即影像的透明度应基于调整后的 EntityBaseP 来计算。

在这里插入图片描述

运行游戏,发现问题似乎已经解决

目前已经解决了绘制和碰撞检测中的一些问题,特别是在位置计算和停止点的处理上,似乎达到了预期的效果。玩家可以正确地在环境中移动,碰撞和停止位置的逻辑也符合预期。

然而,仍然存在一个问题,就是阶梯的碰撞检测。阶梯不会正确与玩家发生碰撞,因为阶梯的高度只达到了地面上方的高度,并未覆盖到玩家可能需要攀爬的区域。因此,需要解决阶梯的碰撞问题,使得玩家能够正确地与阶梯交互。

下一步计划是在阶梯上添加两个矩形,一个位于阶梯的底部,一个位于顶部。这样做是为了能够更好地控制阶梯的碰撞范围,并确保玩家只会在特定的位置与阶梯发生碰撞,而不是轻易穿越阶梯的侧面。这个问题的解决需要对当前的碰撞代码进行一些修改和调试。

game.cpp: 给楼梯添加两个矩形

计划在阶梯上添加两个矩形,一个位于阶梯底部,另一个位于顶部,以便更好地处理阶梯的绘制和碰撞。在绘制时,需要对这两个矩形的位置进行偏移,确保它们准确地定位到阶梯的上下部分。为了实现这一点,需要利用已经实现的偏移机制。

在现有的 PushRect 函数中,已经支持对矩形进行偏移,但是遇到了一些问题。偏移量应该应用于第二个矩形,这样可以确保它与第一个矩形不同,并且根据 Z 轴的高度进行相应的调整。为了便于辨识,底部的矩形会用不同的颜色显示。

然而,当前遇到的问题是,矩形的偏移似乎没有正确应用,导致它们没有按预期位置移动。这可能是因为 Z 轴偏移的处理没有在绘制时被正确使用,虽然代码上看起来已经允许了偏移。

下一步需要检查 Z 偏移的计算是否正确,并确保在绘制时正确应用这些偏移。这可能需要对现有代码进行一些调试和修改,确保偏移量能正确影响绘制过程。

在这里插入图片描述

处理 ZFudge

当前存在的问题是,ZFudge 只用于计算地面点,但没有真正将其应用到 X 和 Y 坐标的偏移上,这导致物体在 Z 轴上的位置被抬高,但 X 和 Y 坐标没有受到影响。为了更好地处理阶梯和其他物体的绘制,想要尝试将 Z 偏移直接应用于 X 和 Y 坐标。

尽管代码的结构比较混乱,但希望通过一些调整,能在现有代码的基础上获得更多的灵活性,而不必深入修改整个系统。为此,考虑将 Z 偏移与 EntityBaseP 结合使用,使得偏移能直接影响物体的绘制。

实验步骤包括去除现有代码中的某些部分,并在需要的位置手动添加 Z 偏移的影响。这可能会导致一些问题,尤其是当 Z 偏移被直接应用时,可能会引入额外的复杂性,因此需要进一步评估这种方法是否合适,并决定是否继续使用该方案。
在这里插入图片描述

检查对 Familiar 的影响

当前遇到的问题是,黄色物体的显示位置不对,导致它似乎消失了。这并不是预期的行为,因此需要调试和找出原因。尽管尝试了多种方案,但仍然没有找到问题的根源,正在进一步检查并尝试解决这个问题。

MetersToPixels 被 OffsetZ 预乘

当前问题的原因在于坐标转换中的错误,特别是“米到像素”的转换方式。问题出在“偏移Z”值与“米到像素”转换的顺序,导致了值被重复乘以“米到像素”,这影响了图形的渲染。为了避免这种重复乘法,应该在处理 Z 偏移时将“米到像素”的转换推迟,确保在正确的位置进行乘法操作。这是当前代码的一大问题,进一步的解决方案可能需要重构这部分渲染代码,避免继续积累更多的“临时修补”方式。
在这里插入图片描述

运行游戏,看到效果更接近正确

当前的问题是在楼梯代码的实现上,特别是在使用地面位置计算时,楼梯的位置仍然不正确。尽管图形渲染已经接近预期,但楼梯的渲染和碰撞检测依然存在问题,导致其显示位置不准确,应该位于玩家角色上方,并且在屏幕中心对齐。需要进一步调试楼梯的代码,并确保其正确使用地面位置的计算结果。这个问题可能涉及到楼梯的碰撞检测逻辑以及如何正确应用地面坐标的偏移。

game.cpp: 不再添加 OffsetZ

在尝试去除偏移量并直接使用 Z 偏移时,图形的显示效果变得更加正确。不过,这种方法可能会在长期的绘制过程中引发一些问题,特别是在处理等距艺术风格时,因为这要求所有的绘制计算必须适应等距视角。尽管目前去除偏移后的结果看起来比较合理,但不确定这种方式是否能长期保持稳定,需要进一步验证和调试。
在这里插入图片描述

在这里插入图片描述

黑板:ZFudge 的作用

Z 偏移量的作用是根据物体在 Z 轴上的位置对其进行缩放,目的是让物体在 Z 轴上越高时,离摄像机的距离越远,从而产生一种透视拉伸效果。这个缩放效果有助于使远离摄像机的物体看起来更远,但也使原本近距离的物体被放大。由于游戏采用等距视角,这种处理方式与实际的 Z 轴深度有所冲突,因为在等距视角下,物体并不直接在 Z 轴上绘制,而是以一定角度呈现,这就导致了视角上的不匹配。

尽管这种视角匹配存在一定的问题,但它是实现特定艺术风格的必要条件,并且是 2D 游戏中常见的挑战之一。当前,角色可以正常地跳跃到不同的 Z 轴高度,且整体效果不错。接下来的工作是继续完善楼梯的碰撞检测,确保它能够正确延伸到天花板以上,以便玩家可以在楼梯上上下行。这项任务是可实现的,且应是当前工作重点。

game_sim_region.cpp: 查看 SpeculativeCollide

为了确保角色只能从楼梯的底部或顶部进入,而不能从楼梯的侧面直接进入并跳到任何位置,使用了一个名为 SpeculativeCollide 的机制。这个机制的作用是限制角色只能在特定条件下与楼梯发生碰撞,确保角色只能沿着楼梯的上下方向行进。

在碰撞检测过程中,结合了 Ground tight 信息,这有助于判断角色是否接触到楼梯的有效部分。这样可以避免角色从楼梯的侧面进入,确保楼梯的碰撞处理仅在角色位于楼梯的底部或顶部时才生效。
在这里插入图片描述

引入 GetEntityGroundPoint

为了简化代码并避免重复计算,决定引入一个名为 GetEntityGroundPoint 的调用函数。这个函数将返回一个实体的地面位置,并且通过将实体的Z维度偏移一半来调整该位置,确保地面位置正确。这样一来,所有需要计算实体地面位置的地方都可以统一调用这个函数,避免在多个地方重复计算,提升代码的可维护性。

例如,在需要获取某个实体的Z位置时,直接调用 GetEntityGroundPoint,这个函数会自动处理位置的偏移。通过这种方式,可以更方便地修改和管理地面位置的计算方式,而不需要在代码中逐一修改所有相关部分。
在这里插入图片描述

使用 GetEntityGroundPoint 设置 EntityBaseP 和地面位置

当前正在考虑如何使用 GetEntityGroundPoint 来计算实体的偏移量,并调整实体位置与地面位置的关系。具体思路是通过获取实体的位置,然后根据其 Z 值计算地面位置,再调整以实现正确的偏移。
在这里插入图片描述

黑板:计算地面位移

这段内容的核心思想是,通过将实体的位置与地面位置进行比较,计算出它们之间的偏移量,从而确保地面正确对齐实体的位置。具体步骤如下:

  1. 实体位置与地面位置的差值:为了避免在不同地方重复计算地面位置,决定使用 GetEntityGroundPoint 函数来获取每个实体的地面位置。然后,通过计算实体位置与地面位置的差值(即实体位置减去地面位置)来得到偏移量。

  2. 计算偏移量:这个偏移量是一个向量,表示从当前地面位置到实体位置的距离。通过这个偏移量,地面高度可以被正确调整。

  3. 通过向量运算调整位置:使用向量减法来计算从地面到实体位置的偏移量,确保实体与地面正确对齐。

总结来说,目的是通过集中计算地面位置,简化代码中的多个计算,并确保以后修改时能一致地应用。

运行游戏,发现现在可以上楼了

现在,修复了上楼的代码,但下楼的问题依然存在。这是因为碰撞检测部分已经正确工作,或者至少已经调试了尽可能多的已知问题。修复后,碰撞检测不再与那些最大值位于地面上的物体发生碰撞,因为它们实际上处于我们下方的地面层。这意味着在地面层上方的物体不会再被误判为碰撞对象。

game.cpp: 使楼梯延伸到地面之上

目前,楼梯的碰撞检测已经正常工作,但存在一个问题:我们无法从上方进入楼梯。问题可能出在楼梯的高度设置上,楼梯被设置得太高,导致我们无法顺利进入。为了改进这一点,计划是让楼梯稍微超出地面层的一定高度,这样可以确保我们在移动过程中能够与楼梯发生碰撞,避免无法进入的情况。

此外,之前提到的“步高”问题也需要处理,考虑到这是影响楼梯交互的一个因素。现在楼梯的顶部虽然可以与玩家正确碰撞,但仍然存在一些小的高度差,可能导致玩家不能顺利进入。这些细节需要进一步调整。
在这里插入图片描述

黑板:理解 StepHeight

目前,楼梯的碰撞检测存在一些问题,特别是在上下楼梯时的交互表现。现有代码的逻辑是,如果玩家在接近楼梯时,步伐与楼梯的高度差大于一定值(例如0.1米),就不能直接跳上楼梯,而必须从合适的高度进入。然而,这个高度差和玩家与楼梯的交互方式存在一些问题,尤其是当玩家尝试从楼梯侧面接近时,碰撞和过渡效果并不理想,造成了一些“跳跃”或不平滑的过渡。

为了解决这个问题,计划对现有的楼梯模型进行调整。当前的楼梯实际上是以坡道形式实现的,而不是传统的阶梯。这意味着楼梯的碰撞矩形应该具有更大的范围,以覆盖整个坡道区域,从而避免因碰撞区域不够大而导致的跳跃或穿透现象。然而,计算地面位置时,并不应该使用整个楼梯的碰撞矩形,而应仅使用一个较小的参考值,例如楼梯的单层高度。这样就能确保玩家能够更加平滑地与楼梯交互,避免过高或过低的触发问题。

这种方式能够让楼梯的碰撞检测更具灵活性,也能为未来的调整提供更多可能性。

game_sim_region.h: 在 sim_entity 中添加 WalkableHeight

为了更好地处理楼梯的交互,考虑了根据不同的楼梯高度变化来调整碰撞检测。当前的方案是通过调整最小Z值来确定“可行走高度”,这意味着在不同楼梯区域,玩家与楼梯的交互将根据楼梯的高度变化来确定是否可以通过。这种方法的目标是确保玩家能够在不同的楼梯高度之间平滑过渡,而不受不必要的碰撞限制。

为了避免在不同楼梯区域之间有太多重复计算,建议引入一个“可行走高度”的概念,这个高度可以通过结合当前楼梯区域的最小Z值与楼梯的实际高度来计算。通过这样的方式,楼梯的碰撞检查就变得更加高效和一致。同时,在实际开发中,这一机制也便于日后的调整,因为只需要在某些区域对“可行走高度”进行修改即可,无需重新编写碰撞逻辑。

这种方法能使得楼梯的交互更加灵活且符合实际需求,尤其是在多层楼梯或不规则楼梯的情况下,可以避免由于碰撞体积设置不当导致的玩家行为问题。

在这里插入图片描述

game.cpp: 在 SpeculativeCollide 中使用 WalkableHeight

我们决定在添加楼梯时,能够指定其上升的高度,这样可以确保楼梯的碰撞区域与可行走区域分离。具体来说,我们会将 entity_sim 结构中的 walkable_height 设置为游戏状态中世界瓦片的深度(以米为单位)。这样,楼梯的碰撞矩形高度就与可行走区域的高度分开了,这有助于在处理楼梯时更好地控制玩家的行为。
在这里插入图片描述

运行游戏,尝试楼梯

在进行楼梯调试时,虽然楼梯的上升部分正常工作,但在尝试下楼时出现了问题。具体来说,存在一个明显的台阶突起,导致无法顺利下楼。尽管其他部分的碰撞检测已经正常,但在楼梯的最底部仍然有些问题。需要进一步检查并修复这个 bug,以确保下楼时不再遇到这种障碍。
在这里插入图片描述

在这里插入图片描述

game_entity.h: 引入 GetStairGround

在进行代码调试时,发现了两个不同的地面计算方式,这可能是导致问题的根源。需要创建一个函数来统一计算地面高度。通过改进现有代码,可以避免不一致的计算,减少潜在的 bug。

进一步的计划是完善实体系统,逐步增加更多的实体特定数据,这样在后续改进和维护时能够更容易地处理各种不同类型的实体。尽管目前的实体系统尚未完全构建,但现有的基础已经具备扩展的潜力。为了避免重复的错误,代码中的一些假设需要被固化,保证系统的一致性和稳定性。

同时,涉及地面点计算的问题也得到了一些澄清,发现并不是 bug,而是代码在某些情况下由于假设不一致导致的暂时性错误。在重构时,需要将 GetEntityGroundPoint 和相关计算步骤整合,确保所有计算使用一致的地面点。通过这些改进,整体的实体系统和地面计算方法将更加健壮,后续的开发和调试也会变得更加高效。

在这里插入图片描述

game_sim_region.cpp: 将 HandleOverlap 和 SpeculativeCollide 改为使用 GetStairGround

在这段内容中,代码的目标是将现有的重叠处理逻辑简化为调用 GetStairGround 函数来获取楼梯的地面高度,并保留原有的 GetEntityGroundPoint 函数调用作为备份,以防未来需要对 X 和 Y 方向进行调整。以下是详细总结:

  1. 简化代码:原本有多个处理重叠的代码段,现在决定使用 GetStairGround 来计算楼梯的地面高度。这样可以避免重复代码,并集中处理楼梯地面的计算。

  2. 保留备份:尽管不太可能,仍然保留对 GetEntityGroundPoint 函数的调用,以防未来需要在 X 和 Y 方向进行位置调整。这样做可以增加代码的可扩展性和容错性。

  3. 移除冗余代码:在楼梯的重叠处理部分,移除了不再需要的代码,特别是与重叠处理无关的内容,如检查两个条件的代码。这些检查似乎是多余的,因为处理楼梯的唯一标准应该是“需要跨越的高度”。

  4. 确认类型:为了避免发生不必要的错误,增加了类型检查,确保调用 GetStairGround 时,传入的实体确实是楼梯类型。这样可以防止错误调用其他类型的实体并导致程序崩溃。

  5. 待处理问题:代码中提到还存在一些可能没有完全实现的部分,并标注为需要进一步工作的地方。这可能是为了后续的优化和功能扩展做准备。

整体来说,目的是通过精简和重构现有的重叠处理逻辑,让代码更加简洁、清晰,并提高其可维护性,同时为将来可能出现的需求留有余地。
在这里插入图片描述

运行游戏,发现问题得到解决

目前的情况看起来进展不错,已经有很多功能能够正常工作,虽然仍有一些不完美的地方。地面高度的计算是一个主要问题,但整体效果已经有了显著的改善。不过,仍然出现了一些异常,尤其是某些地方的表现并不符合预期,可能是存在bug。比如在角色下楼梯时,某些动作没有完全按照预期进行,需要仔细检查并修复。

game_sim_region.cpp: SpeculativeCollide 需要知道是上楼还是下楼

当前遇到的问题是关于处理楼梯的碰撞和上下楼梯的地面类型。需要解决的核心问题是如何让碰撞系统能够正确处理从楼梯上移开或走上楼梯的情况,确保能够识别楼梯之外的地面类型。这涉及到对地面高度的规范化,并且在碰撞循环中考虑高度变化,避免不合适的高度变化导致物体无法正确移动。

接下来计划解决的问题是:在碰撞系统中加入处理地面层级的概念,使得碰撞可以正确处理跨越楼梯等地形的情况。同时,还需要进一步确保不同的地面高度在不同的区域能被正确处理,确保碰撞系统能准确判断和限制物体的移动范围。

总的来说,今天完成了预期的一些任务,但仍有一些细节需要进一步完善,尤其是在碰撞和地面处理方面。计划在明天继续深入解决这些问题,并对地面层级进行更细致的设计,以确保系统能够正确处理不同高度的过渡。

问答环节

问:你在 Linux 上使用 Clang 吗?

在Linux系统上使用clang编译器,在Windows上则使用Visual Studio的编译器。同时,虽然他们曾经在Mac上进行开发,但目前已经不再频繁使用Mac进行项目发布,因此对Mac的开发环境不再熟悉。

问:从零开始自学 C++ 的最佳方法是什么?

关于如何从零开始自学C++,程序员建议最好的方法是通过大量的编程实践来学习。首先,可以从一些基础的教材入手,比如《C程序设计语言》这本书(K&R),这本书对于理解C语言及其思想非常有帮助。除了阅读书籍,观看相关的编程直播,观察别人是如何编程的,尝试模仿和理解这些操作也是一种很好的学习方式。

程序员提到,自己学习C++的经历已经过去很多年,因此不太记得具体的学习材料,且也不清楚现在是否有特别推荐的入门教程。不过,持续编写代码和解决问题是自学C++的核心。

问:你知道 Voxpel 编程吗?

对于Vox pel编程,程序员表示自己不太清楚这个术语的含义,推测它可能与Voxel(体素)有关。虽然不熟悉Vox pel引擎的编程,但他知道如何编写体素引擎。

问:你打算把家里的楼梯换成坡道吗?

我们在游戏设计中加入了一个能够平滑上下来回滑动的楼梯,感觉非常好,甚至比传统游戏中的楼梯更顺畅。最初并没有打算加入坡道,但由于这一滑动体验太令人满意,我们决定保留这种设计,并在未来进一步完善。我们也注意到游戏中常见的2D楼梯处理方式,通常角色会触发固定动画并转屏切换,而我们的设计则没有这种切换感,而是通过平滑的滑动让玩家能够自如上下楼层,带来更好的体验。尽管现实生活中不会实现类似坡道,但我们决定在游戏中继续沿用这一创新设计。

问:你是怎么让 Visual Studio 调试视图的右侧垂直分割的?

如何在 Visual Studio 调试器中将窗口分割成垂直布局。方法很简单,只需将窗口(如模块窗口)拖动到屏幕上。当拖动窗口时,会看到一个类似指南针的指示符,若将窗口放置在其中一个区域,窗口会自动对齐。如果放置在其他区域,则会分割窗口。这样可以根据需要自由调整窗口布局,例如创建多个窗格,或者将窗口分为上下或左右不同的布局。

然而,在旧版本的 Visual Studio(如 2008 版)中,存在一个严重的 bug:尝试对窗口进行停靠时会导致程序崩溃,而微软在其知识库中明确表示该问题不会修复,建议用户避免使用这一功能。但在较新的版本(如 2013 版)中,这个问题已经解决,不会再发生崩溃。

问:为什么你在代码中使用这么多魔法数字?

这里的“魔法数字”指的是代码中未经过清晰命名的常量值,这些值往往在代码中没有解释其含义,导致代码不易理解和维护。

问:你怎么看待友元类?

在开发中,认为使用 friend 类是多余的,觉得会浪费打字。由于不使用 private,因此也没有必要使用 friend

问:这是不是变成了反向 Doom?几乎是 2D 渲染 3D,而不是 3D 渲染 2D?

在讨论游戏渲染时,提到了一种“2D渲染在3D中”的设计方式,类似于经典的《DOOM》中的“2.5D”视角,但方式有所不同。《DOOM》采用了近似的3D效果来表现墙面,实际上仍然是2D渲染,而我们则是通过精灵分割来实现,精灵本身没有倾斜,而是采用了3D定位系统。这种设计可以理解为“反向DOOM”或“2D渲染在3D中”。

我们认为,确保3D基础结构的稳固非常重要,因为这可以避免开发过程中出现意外问题,减少临时处理的需求。虽然2D渲染方式可能有点“hacky”,但考虑到实现成本相对较低,这种方法仍然是值得尝试的。通过提前实现扎实的3D基础结构,能够确保后续开发中不会频繁遭遇问题,避免不断进行临时的解决方案。

问:如果你上楼进入一个封闭的房间,最上层会不会渐变显示?

在讨论游戏中的楼梯和房间的渲染时,提出了一个问题:当玩家从楼梯上走到一个封闭的房间时,最上层是否应该渐变显示。对此,猜测可能会采用渐变效果来解决这个问题,但也表示目前还不确定具体的实现方式。由于这个问题还需要进一步的实验和调整,因此暂时没有最终的解决方案,仍然需要一些尝试和探索。

问:你计划什么时候对精灵进行 Z 排序?

在讨论精灵的Z排序时,表示计划在渲染器实现时进行,但预计这一部分的工作不会在短期内完成,可能还需要一段时间,几个月后才会开始着手。

问:你为什么在代码中使用这么多魔法数字?为什么有这么多 #define?

在讨论代码中的“魔法数字”时,解释了为什么有些数字没有使用宏定义(#define)。如果某个数字只在局部使用,且没有在其他地方引用,那么就没有必要将其定义为宏,否则会污染全局命名空间。如果某个数字在多个地方使用,那可能就是一个需要改进的地方,可以提出指出,看看是遗漏了还是有其他合理的原因。

问:你打算使用高级着色器技术吗?如果是,你打算使用哪些?

在讨论是否使用高级着色器技术时,表示计划使用一些高级着色器技术,但目前还为时过早,具体细节将在未来的开发中逐步实施。

问:看起来我错过了一集,你在其中实现了从高层看到低层。你记得那是在哪集吗?将来地板会保持透明吗?

在讨论渲染器时,提到地板不会保持透明,尽管目前地板是透明的,这样做比较方便。未来会添加地面,可能会首先加入一个占位符地面,而不是保持透明。同时,还需要处理如从上层下降到下层时,如何渐变处理上层的显示效果等问题。这部分的工作计划在接下来的开发中进行,但具体细节仍在考虑中。对于何时实现这个功能,也没有明确的记忆或时间点。

问:如果我没记错的话,早期我们开始使用角色底部中心位置进行碰撞检测,然后改为中心位置,并且在 X 和 Y 方向上有所偏移。现在似乎又回到了使用中心 X 和 Y,并继续计算底部中心位置。你认为是否需要将这一点整合起来?

在讨论碰撞检测时,提到最初使用的是角色底部中心位置来进行碰撞检测,后来调整为中心位置,偏移了x和y坐标。现在,似乎又回到了使用中心x和y坐标的方式,同时保留了底部中心的位置。关于是否需要将这些方法合并,认为目前的做法更合理,因为统一处理x、y和z坐标更加简洁,避免了不同坐标轴上采用不同的处理方式,这样可以简化数学运算,避免在处理复杂的碰撞检测时出现混乱。如果让碰撞检测的不同部分(如Minkowski和干涉测试)在x、y和z上使用不同的方式,可能会增加数学复杂度,影响效率。因此,统一处理所有坐标轴并单独处理与地面相关的偏移,似乎是更明智的选择。尽管如此,这个决定仍然有可能在未来被重新评估。

问:森林中间漂浮的头是怎么回事

森林中飘浮的头部是一个“伙伴”,它会跟随玩家四处移动。

问:能解释一下 game.h 中的这一行吗?ControlledHeroes[ArrayCount(((game_input *)0)->Controllers)];,看起来你在强制转换一个空指针并引用它

无法直接获取数组成员的大小,因此需要通过一些技巧来绕过这个限制。目标是计算数组的大小,但C语言不允许直接对类型或成员使用sizeof,必须使用实际的变量或值。因此,采取了一个技巧性的方法,使用一个空指针并将其强制转换为正确的类型,模拟对该数组的引用,从而间接计算数组的大小。这种做法虽然看似不太优雅,但由于C语言的限制,这是目前的解决方法。

问:为了绕过 Mischief 缩放问题,你能先找到想要的缩放级别,然后在四个角上画四个点,接着再回来对齐这些点到角落吗?

关于Mischief缩放问题的解决方案。提出了一种方法,即找到需要的缩放级别后,在每个角落绘制四个点,然后回来时通过对齐这些点来恢复视图。但这种方法被认为不太方便,因为每次都需要找到这些点。目标是找到一种可以直接设置缩放的方式,而不需要不断地定位这些点。

你可以使用 C++ 的 decltype 或 typeof 来找出 ArrayCount

在讨论C++中使用decltypetypeid等特性时,提到尽管这些功能可以帮助获取类型信息,但由于它们传统上并不总是得到很好的支持,因此尽量避免使用这些特性,尤其是对1990年代的C语言风格更为偏好。虽然decltype可能在某些情况下有用,但对于目前的需求,仍然更倾向于使用C语言的子集。对于如何准确获取类型信息,提出了一个假设的做法,可能通过decltype获取控制器数组的大小,但也承认这部分实现可能还存在一些未知的问题,决定将其作为读者的练习留待解决。

问:为什么你计划使用 OpenGL 或 DirectX 进行硬件加速?实现这一点需要了解实际的 GPU 架构吗?

在讨论为何选择使用OpenGL或DirectX时,指出这两个是唯一能够有效访问3D硬件的API。现代计算机的CPU无法高效地进行图形渲染,因此必须使用GPU来渲染游戏。虽然自己编写渲染器作为教育项目,但最终不会将其作为游戏的主要渲染方式,因为CPU渲染无法与GPU渲染的速度相比。

问:你怎么看待 Khronos 的 Vulkan?

对于Vulkan的看法,目前尚未收到其规格说明,因此无法做出具体评价。理想情况下,希望硬件接口尽可能简化,理想的状态是通过环形缓冲区与硬件直接交互,而不需要驱动程序。如果Vulkan比现代OpenGL更接近这一目标,那么它会是一个积极的进展。具体好处取决于Vulkan的设计质量,如果设计得当,将是一个显著的提升;如果设计不理想,则可能仍然是一个改进,但不那么显著。

问:当你知道如何编程但没有艺术技能时,做游戏的最佳方式是什么?找个艺术家来为你做吗?这是我的软肋,但我想自己做个游戏

如果有编程能力但缺乏艺术技能,最好的方法是雇佣一位艺术家来完成视觉设计。但如果预算不足,或者没有艺术技能,可以考虑制作程序生成的游戏。很多成功的程序员都通过简单的艺术风格获得了受欢迎的游戏。可以尝试制作3D游戏,利用光照来弥补艺术设计的不足,或者通过简化图形定义来减少对复杂艺术内容的需求。

例如,可以通过几何形状来创建游戏视觉,或者借用现有的视觉设计,比如《迷你地铁》这款游戏,它的视觉设计非常简洁,主要是基于地铁线路图。因此,即使没有高端的艺术制作能力,也可以通过借鉴已有的简单设计来构建游戏,避免被艺术内容所限制。总之,如果无法承担艺术制作,最好定义一个能够不依赖复杂艺术而依然能吸引玩家的游戏设计理念。

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

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

相关文章

【Java基础】正则表达式的使用与常用类分享

1. Java 正则表达式 正则表达式定义了字符串的模式。 可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 1.1 正则表达式实例 一个字符串其实就是一个简单的正则表达式,例如 Hello World 正则表达式匹配…

第30天:Web开发-PHP应用组件框架前端模版渲染三方插件富文本编辑器CVE审计

#知识点 1、安全开发-原生PHP-开发组件集合 2、安全开发-原生PHP-模版引擎渲染 3、安全开发-原生PHP-第三方编辑器 组件/框架 说明 [Web框架] Laravel 现代化、功能全面的框架,适合大多数Web应用。 Symfony 高度模块化、功能强大的框架,适合复杂…

with as提高sql的执行效率

实战sql with cte(UNIT_ID, UNIT_NAME, PARENT_UNIT_ID, UNIT_CODE ) as (select UNIT_ID, UNIT_NAME, PARENT_UNIT_ID , UNIT_CODEfrom HPFM_UNITunion allselect t.UNIT_ID, t.UNIT_NAME, t.PARENT_UNIT_ID, t.UNIT_CODEfrom HPFM_UNIT tjoin cte on t.PARENT_UNIT_ID cte.U…

计算机网络 (29)网络地址转换NAT

前言 网络地址转换(Network Address Translation,NAT)是计算机网络中的一种重要协议,它主要用于将私有IP地址转换为公共IP地址,以实现内部网络与外部网络之间的通信。 一、基本概念 NAT是一种在局域网(LAN&…

Docker--Docker Volume(存储卷)

什么是存储卷? Docker的存储卷是一种将宿主机的本地文件系统中的某个目录与容器内部的文件系统中的某个目录建立绑定关系的机制。这种绑定关系意味着,当在容器的这个目录下写入数据时,会同步到宿主机的这个目录中;同样&#xff0…

STM32裸机开发转FreeRTOS教程

目录 1. 简介2. RTOS设置(1)分配内存(2)查看任务剩余空间(3)使用osDelay 3. 队列的使用(1)创建队列(1)直接传值和指针传值(2)发送/接收…

用豆包MarsCode IDE打造精美数据大屏:从零开始的指南

原标题:用豆包MarsCode IDE,从0到1画出精美数据大屏! 豆包MarsCode IDE 是一个云端 AI IDE 平台,通过内置的 AI 编程助手,开箱即用的开发环境,可以帮助开发者更专注于各类项目的开发。 作为一名前端开发工…

PySide6的样式表

PySide6 提供了对 Qt 样式表(Qt Style Sheets,简称 QSS)的支持,这是一种类似于 CSS 的样式表语言,用于自定义 Qt 应用程序的外观。 1. 什么是 Qt 样式表(QSS) Qt 样式表是一种声明性的样式表语…

android 启动页倒计时页面编写

一、需求和技术 1、实现5,4,3,2,1启动页倒计时 2、倒计时实现使用CountDownTimer 二、activity代码 public class OpenActivity extends AppCompatActivity {private Button in;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanc…

PCB原理图的编译设置

设置步骤: 进入-->Project Options...,对照设置“致命错误”部分来设置即可

LInux单机安装Redis

1. 安装gee工具包 由于Redis是基于c语言编写的所以安装的时候需要先安装gee以及gcc的依赖,yum云用不了可以看一下这个 linux 替换yum源镜像_更换yum镜像源-CSDN博客 yum install -y gcc tcl 2. 添加redis的压缩包 3. 上传到Linux 上传到 /usr/local/src 目录、这个目录一般用于…

键盘鼠标共享工具Barrier(kail与windows操作系统)

键鼠共享工具Barrier(kail与windows操作系统)_barrier软件-CSDN博客 sudo apt install barrier

黄仁勋演讲总结(2种显卡,1个开源大模型,1个数据采集平台)

研发算力显卡RTX50系列,PC端显卡GB10,开源大模型Cosmos(用于机器人和自动驾驶), Isaac GR00T(人形机器人的数据采集平台)。 新一代 RTX 50 系列显卡 RTX 50 系列 GPU,相对之前系列&a…

Linux内核学习——数据结构

文章目录 链表双向链表哈希链表 红黑树无锁环形缓冲区映射参考 内核版本:linux-6.6.69 longterm 链表 双向链表 Linux内核实现了一套纯链表的封装,链表节点数据结构只有指针区而没有数据区,另外还封装了各种操作函数,如创建节点…

批量写入数据到数据库,卡顿怎么解决

在批量写入数据到数据库时,遇到卡顿或性能瓶颈是比较常见的问题。以下是一些可能的解决方案和优化策略,帮助你提高批量写入的性能: ### 1. **批量大小优化** - **调整批量大小**:尝试调整批量写入的数据量,找到一个平衡点。过大或过小的批量大小都可能影响性能。通常,批…

初学Linux电源管理

学习文档出处: 万字整理 | 深入理解Linux电源管理:万字整理 | 深入理解Linux电源管理-CSDN博客 电源管理 因为设备需要用电,而且设备中的各个硬件所需要的电压是不一样的。故计算机需要对硬件的电源状态管理。但是电能并不是免费的&#x…

基于开发/发布/缺陷分离模型的 Git 分支管理实践20250103

基于开发/发布/缺陷分离模型的 Git 分支管理实践 引言 在现代软件开发中,合理的分支管理策略是保证项目成功的关键因素之一。本文将详细介绍一种基于开发/发布/缺陷分离的 Git 分支管理模型,这种模型不仅能提升团队协作效率,还能确保代码质…

数据库回滚:大祸临头时

原文地址 什么是数据库回滚? 数据库技术中,回滚是通过撤销对数据库所做的一项或多项更改,将数据库返回到先前状态的操作。它是维护数据完整性和从错误中恢复的重要机制。 什么时候需要数据库回滚? 数据库回滚在以下几个场景中很…

1月7日星期二今日早报简报微语报早读

1月7日星期二,农历腊月初八,早报#微语早读。 1、公安部:已为一线民警配备执法记录仪130万余部,规范现场执法; 2、浙江提出2035年全省域基本实现共同富裕; 3、“汕头牛肉丸”有新标准!1月6日起…

数据结构:时间复杂度和空间复杂度

我们知道代码和代码之间算法的不同,一定影响了代码的执行效率,那么我们该如何评判算法的好坏呢?这就涉及到了我们算法效率的分析了。 📖一、算法效率 所谓算法效率的分析分为两种:第一种时间效率,又称时间…