打击框与受击框hitbox and hurtbox

欢迎阅读本系列介绍性文章的第四部分,内容介绍了开发格斗游戏背后的魔法!

在前面的部分中,我们已经讨论了2D 与 3D、要添加的特性以及如何架构角色状态机逻辑。


(资料图片)

现在,让我们深入研究一下技术细节!

挨打受伤的地方

格斗游戏的一个核心概念是,角色只能用/在他们身体的某些部位击中或被击中,这可能会因执行的动作、角色状态、角色是否在移动以及几个不同的因素而有所不同。

这通常是通过分别使用两个(或三个 - 见下文)特定对象来完成的,这些对象分别称为打击框受击框

打击框正是它在罐子上所说的那样:它们标记了你的角色可以对对手造成伤害的部分。它们通常仅在攻击期间激活,并且仅在特定数量的帧(称为招式的持续)期间激活。

受击框恰恰相反:这些对象标记你的角色可以被击中的位置并且通常总是处于活动状态,除非角色处于特殊状态或执行一些无敌的动作。

通常,打击框和受击框是动态对象,它们会每一帧会改变位置。是的,每一帧你都必须向游戏引擎提供每一个打击框和受击框的位置信息,以便执行适当的碰撞管理。

正如我之前提到的,还有第三类,有时是前一类的子集。由于我还没有找到一个正式的名称,我将使用这个术语碰撞框collision box来引用它。基本上,它们标记了玩家不能重叠的区域,限制了角色精灵/模型之间可以相互靠近的距离。

2D和3D的实施细节有所不同,我们将分别进行分析。请注意,3d风格的2d格斗游戏可以使用其中任何一个:例如,街头霸王V使用2D方法。

测试你的能力

打击框是每个招式的核心。当你定义一个招式时,你必须指定打击框,以及它们在击中时造成的伤害,对手需要做出的反应,被打击框击中后对手不能移动的时间(准确的说就是hitstun受击硬直).这是相当多的工作,可能有点烦人,因为每一个招式都必须要做,在每一个动画帧

这就是3D和2D的区别所在:在2D游戏中,您必须在每一帧手动创建并移动打击框,以适应您正在使用的精灵,而在3D游戏中您可以将打击框框作为不可见的“子对象”附加到角色模型。这将使事情变得更容易,因为框体将与手臂、腿和其他身体部位一起移动,需要较少的维护,但牺牲了一点灵活性。因此,如果你有一个高帧率(比如说60fps),3D对于单人开发者和与角色模型相关的移动来说肯定更容易,而2D允许在与一般招式相同的难度下制作进行更奇怪的招式,不幸的是,从一开始难度就更高。

2D开发者的捷径是利用共享相同打击框/受击框位置和大小的帧,从而步骤数量更少且更易于管理。

Baby, don’t hurt me! Don’t hurt me! No more!

对打击框表达的所有担忧也适用于受击框:您还必须在每一帧正确跟踪它们,但这次您只需确保它们在当前帧处于活动状态以检查碰撞。

受击盒必须在某些方面与角色精灵/模型相匹配:当他们不这样做的时候,虚空判定就会出现,给玩家留下不好的印象(转到第一分钟02:47明白我的意思):

https://youtu.be/XOn7qDt9AJg

哦,3D打击框的悲哀…

明白我的意思吗?没有什么比用你的角色的靴子的看不见的尖端击中对手胳膊和腿之间的空白空间来击败对手更令人不满意的了(尽管粒子效果可以提供一个不错的掩饰)。所以,你不仅要移动它们,还要让它们符合玩家的期望。

离我远点!

碰撞框(有时称为推动框)并不总是需要的:有时你可以只需要检查受击框盒之间的碰撞来确定玩家是否重叠。在以下情况下,它们只有在你想要角色在使用招式过程中以受击框盒不允许的方式重叠是必要的,(想象一个飞踢,攻击者的腿有一个受击框,但必须越过对手的身体才能击中)。

大多数时候,打击框比角色的受击框小(作为一个明显的例子,来自拳皇14的陈国汉)。

作为打击和受击框,碰撞框必须在每一帧跟踪精灵/模型。

程序员的小炒:如何实现所有的这些?

2D: 圆形和矩形

现在你已经知道了基础知识,一个简单的问题可能会出现:我如何有效地实现这些事情?答案是:这需要耐心和一点简单几何学的帮助。

在2D中,最容易管理的两个形状是圆形长方形,因为它们需要简单的算法和很少的计算时间来检查重叠。

圆完全由三个参数定义:圆心坐标的(X,Y),半径。矩形由四个参数定义:左上角的(X,Y)和右下角的(X,Y)。

例如,如果你将所有的打击框和受击框构建成矩形或圆形(其中之一或另一),那么每一帧你只需检查两个形状是否发生碰撞。

以下是矩形的仿真代码示例:

圆甚至更容易检查,但它们可能不足以满足您以有效方式覆盖精灵形状的需求:

圆形和矩形是2D中两个最简单的解决方案,是近似性和易用性之间的合理折衷。

在每一帧,你应该存储每个打击框和受击框的位置,并检查重叠部分。每一个招式和角色状态都应该有自己的一组打击框和受击框,按帧列出。你也可以插入帧之间的位置,以减少您的工作量(例如,您在第1帧和第5帧定义了伤害框位置,然后执行线性内插法https://en.wikipedia.org/wiki/Linear_interpolation随着时间的推移来发展它,而不必在每一步都重写它),但它仍然需要大量的耐心和奉献精神来为每种情况准备适当的框体。

3D: 球体,无处不在的球体

添加第三维度从一个方面来说使事情变得更容易:因为你没有精灵而是模型,你可以将打击框/受击框附加到模型的骨骼上,这样它们就可以随着动画一起移动。

从一方面来说,这是一种简化,但从另一方面来说,这意味着角色在例如空闲姿势时的移动可能会使一些攻击只在非常特定的帧连接

另一个不可忽视的问题是如何管理3D中的碰撞。第三维让事情变得更难,因为,你知道…三维旋转。

因此,如果您不想陷入射线追踪、矩阵变换和奇怪的几何怪圈,最直接的方法是使用球体。

因为它们仅由四个参数定义,即中心点(X,Y,Z)和半径检查碰撞的代码基本上是2D圆算法的简单扩展。此外,节省了计算时间并降低了过程的复杂性。你不必关心旋转

然而,你显然必须关心球体如何很好地映射角色模型。

作为例子, 超级任天堂明星大乱斗Melee 使用球体作为打击框和受击框https://smashboards.com/threads/link-hitboxes-and-frame-data.306010/。 它们的旋转独立性是远远超过其他选项(方框、椭圆)的优势,如果你找到合适的算法,如果你的引擎提供一些智能解决方案来检查它们的交集,或者你想尝试一些不同的东西,的时候都可以考虑这种方法。

综上

格斗游戏是基于框体管理的。定义合适的点击框和伤害框对你的游戏可玩性至关重要。2D游戏需要更多的关注如何正确定位/使用打击框,但是碰撞检查相对简单。另一方面,3D游戏在打击框和受击框放置方面帮了你很多,但如果你没有掌握3D几何,可能会变得难以管理。

今天就够了!如果你觉得这篇文章有用,请告诉我,不要忘记在Twitter上给我发你的建议(@AndreaDProjects)

下次见

推荐内容