卡梅隆·纽汉著?如果有人还没有,现在就是去做的好时机。部分原因是这是一个极好的水平,充满了狡猾的伎俩(特别是对枪管,因此得名)和一些激烈的战斗。是经典的早期末日PWADs之一(发布于1994年5月),虽然它在建筑和纹理上显示了它的年龄,但它也有一些很棒的拼图和战斗(它是一个令人兴奋的级别,所以可能不是每个人都喜欢)。更重要的是,这是我经历这个错误的第一个级别,也是我知道的唯一一个很难不注意到这个错误的级别。让我们来布景吧。你只有一把手枪,没有多少弹药,还有那把电锯。你正俯视着一间黑暗的房间,前面有一个坡道,可以到达房间的一半,朝向一层的壁龛,里面有一张钥匙卡。坡道的两边各有一条坡道。你沿着坡道往前走,它就会慢慢地进入房间。房间的每一个角落都是圆角的,所以你可以在没有防御性的地方战斗--除了隐蔽的地方。所以你跳进远处的壁龛,转过身来,开始用链锯锯向你走来的石块。你就会被屠杀。
现在电锯有时会有点狡猾,当然在那些日子里我不是一个特别好的球员。但这场战斗似乎格外艰难;电锯就是打不住,而且,尽管开场很窄,但它似乎错过了很多幽灵的身影。几次尝试后,我经历了一次可以接受的健康损失,尽管损失很大,但我还是继续玩下去,然后就忘了这件事。
几年后,我正在为我的网站写末日评论,并决定重温这一关卡。我又被这场比赛打得落花流水。这一次,我确信不只是我过了糟糕的一天,这个房间真的有什么东西把我搞得一团糟。然而,在编辑器中加载关卡并没有什么花招,只是一个简单的房间。所以我又一笔勾销了。
现在,我相信有一些纸上谈兵的评论家正在阅读这篇文章,他们更愿意看到这个错误为他们演示。要么是因为你在加载关卡时使用工具,要么是因为你被描述为拼图关卡而感到厌烦。更精明的批评家会认为,我在谈论的是一个PWAD,而且是一个不同寻常的项目--。
毕竟是一个谜题级别,仅仅因为链锯房间的把戏超出了我的智慧,并不意味着它在某种程度上就不是真正的把戏。不管怎样,这是另一个演示。它甚至不是我做的,所以你可以把它归咎于我糟糕的末日技能。这是在一个原始的水平,所以你不能责怪它的PWAD的作者。试试(MAP16)的这个演示。简单的总结是:玩家钉住一名中士,向他开枪--但子弹穿过了中士,击中了后面的围墙。
所以,我认为线路攻击的代码有问题。我所说的直线攻击,指的是末日战神处理为instantaneoushit-first-object-in-a-straight-line攻击的任何攻击,包括子弹和BFG痕迹(而不是像火箭这样的投射攻击,它会产生一个缓慢移动的物体,通过接触或爆炸造成伤害)请注意,末日之战中的链锯-所有的咬人、抓取和其他近战攻击-都被简化为非常近距离的直线攻击。在这里,我指的是末日战神处理的任何攻击,包括子弹和BFG痕迹(而不是像火箭这样的投射攻击,它会产生一个缓慢移动的物体,通过接触或爆炸造成伤害)。它似乎错过了应该击中的目标。线对物碰撞检测代码有问题。
是时候来点技术上的东西了。Doom中的冲突检测是在称为块图的结构的帮助下处理的。这是WAD中最简单的数据结构之一:它将级别分解为128×128个正方形的网格(称为块图块,或简称为块)。BLOCKMAP列出了每个块中存在的线框(墙等)。128x128是4个远程端口焊盘的大小,这是一个用于冲突检测的任意但方便的大小。在游戏中,末日不仅保存了每个方块的行列表,还保存了该方块当前所在关卡中所有物品的列表。
假设末日要测试玩家是否与实体对象发生了碰撞。Doom首先列出玩家与之重叠的所有块图块(通常只有一个,但如果玩家正好站在块的一角,可能多达四个)。然后末日将仔细检查每个方块中包含的物品列表,并对每个物品进行测试,以查看玩家是否正在触摸它。通过使用块图,Doom知道它只需要测试包含在附近块中的那些对象:这显然比针对关卡中的每个对象进行测试要快得多。
然而,眼光敏锐的读者可能已经在这个算法中发现了一个错误。玩家可能会重叠几个块,因此末日将检查所有的块;但是其他对象也可以重叠成几个块。假设玩家完全包含在一个街区中,但是一个Mancubi正好站在下一个街区的边缘上;Mancubi将重叠在两个街区上,因此我们必须对这两个街区的玩家进行检查。DOOM通过在计算出要检查的块的列表时向对象的半径添加一个模糊因子来补偿这一点,该模糊因子被称为MAXRADIUS,并被设置为64个单位(作为比较,这是一个远程端口衬垫的宽度)。这个想法是,MAXRADIUS应该大于游戏中任何物体的半径,所以如果我们把MAXRADIUS加到一个物体的半径上,我们应该有一个包含可能阻碍它的物体的区域的外部边界[1]。
现在让我们考虑另一种情况:测试一条线(例如,猎枪弹丸)与什么碰撞。在本例中,Doom列出了这条线穿过的所有块图块的列表[2],并(按顺序)逐个遍历这些块,测试每个块中的所有对象,直到找到被这条线击中的对象为止。再一次,Doom只测试线条所经过的块图块中的对象,从而节省了大量的工作。
我们再一次遇到了阻挡站在积木边缘的物体--让我们称它们为目标--的问题。具体地说,是指站在与直线不相交的区块边缘,但与与直线相交的区块重叠的目标。末日需要检查这条线是否击中了这个目标,即使它没有站在横穿的方块中。我们需要一个等价于MAXRADIUS的黑客,但是线条没有半径;最接近的等价物是想象绘制一条宽线,就像在Paintshop Pro中用粗笔画一样,但这将比画一条细线要多得多,代码也要差得多。不管是什么原因,Doom程序员忽略了这个问题:Doom不允许行冲突代码中的几个块重叠的对象。
既然我们有一个真实的例子,让我们看看这在实践中是如何工作的。考虑一下演示中的场景,球员和中士脚趾对脚趾地站着。在ISAT方块图的左下角(-2666,-2440),中士站在(-608,1272),玩家站在(-645,1274)。我们想要计算出它们相对于块图的位置,所以我们从每个对象的坐标中减去块图原点,然后除以128(块图块大小)。实际上,我们对它们在哪个块图单元不是很感兴趣,而是对它们在那个块图单元中的什么位置感兴趣:我们想知道除法的其余部分。
所以它们在相邻的区块中,这是合理的,因为它们正好毗邻在一起。更重要的是,中士就在他的街区的边缘(偏移量(10,0),所以他死在了街区的南边)。玩家也在街区的边缘附近,并且将平行于那个边缘投篮。如果玩家直接向东射击,他的射门将穿过街区(16,29)并击中中士;如果玩家只向南/右稍微射门,那么射门将进入(16,28)街区,因为它没有进入(16,29),所以它将错过中士。如果你看一下屏幕截图,你会发现玩家的角度有点偏南。
请参见右侧的图表。玩家和中士都在东西区块图线上,这条线将(15,29)和(16,29)与(15,28)和(16,28)分开。如果玩家击中中士在线上方的部分,末日将会记录一次命中。如果球员击中了底线以下的部分,那就是错误的。有效地说,玩家在任何一次射击中都有50:50的机会命中。使用猎枪,武器的自然散布略微提高了这些几率,但仍然有很好的机会让大部分或所有的弹丸落在底线以下。
红钥匙房。同样,玩家是绿色的,怪物是红色的,这一次我展示了玩家的电锯攻击路线。我添加了黑色的墙,块图的单元边框是蓝色的,攻击进入玩家右边的单元,但是恶魔在那个单元下面的单元中,所以攻击失败了。当玩家和目标离得很近时,这个错误就更重要了。在很远的距离上,它仍然在那里,但是猎枪的自然散布,以及链枪和手枪中的随机元素,会使射击更分散,因此在一侧持续遗漏的可能性较小。在远距离,一些弹丸会命中,但不是全部;在近距离,要么全部命中,要么一无所有。
举例说明,它对玩家的影响更大。这不是因为代码中的任何原因,而是人为的原因:玩家总是犯错误。如果你向右瞄准了一小部分,没有击中怪物,如果你相信它会击中的话,下一枪你会倾向于在相同的地方开枪。怪兽的瞄准也很差,但这次
在我们离开这个话题之前,让我们看看这个错误是否能得到任何积极的利用。毕竟,Doom是一款缺陷真正是功能的软件--至少,每个人似乎都是这样对待它们的。那么,我们能像以前那样利用这个缺陷吗?这个问题不言而喻,但有什么用呢?
假设我们想要设计一个关卡,让玩家可以很容易地错失他们的投篮。我们已经说过,当球员面向北、南、东或西的时候,错误会更有效,所以我们把球员放在一个与网格对齐的通道网络中。当设置为128x128时,请确保所有通道的排列方式为沿栅格底部或栅格左侧上方。然后,在地图的左下角添加一个虚拟扇区,其左下角为(-96,-96);这将固定块图的原点。你可以将关卡中的每一段都被块图一分为二。当玩家射击时,如果他们瞄准一边,而怪物站在另一边,他们就会打偏,即使射击应该击中。那我建议你出版并被诅咒。事实上,我会买寿险并更改你的地址,因为外面会有很多末日之星永远恨你。
这个虫子还有其他用途吗?嗯,有人建议参加比赛的玩家可以知道区块图线在某一关卡的位置,并规划路线和站立的地方,使它们处于区块图的边缘。但在死亡比赛中,比赛往往更疯狂,所以我怀疑玩家在沿着轴线投篮上花的时间比单人比赛要少,因为单人比赛的速度要慢得多。投射武器不会受到这个错误的影响,而且BFG的痕迹非常多,传播得很好,即使是局部保护也不太可能拯救一个玩家。因此,虽然它会提供一点额外的保护,但我怀疑它是否和仅仅保持移动一样有效。
让我们不要忘记这个错误的主要用途:当你错过了至关重要的一枪并喝醉了的时候,你可以责怪Carmack!:-)。
一个有趣的问题仍然存在:卡梅隆·纽汉姆是否故意使用区块图漏洞?这一关使用了很多聪明的末日诡计,比如传送枪管和触发防线。但在末日的历史上,这样一个鲜为人知的漏洞被积极利用似乎还为时过早。不过,这并不是说这个关卡不是为它设计的;很难不注意到这个关卡的漏洞,所以他肯定会在测试中注意到这一点,如果不能解释它,他就会让它保持原样,并相应地调整难度。我想我们可以说他使用了窃听器,但很可能并不了解它。
感谢Babdko提供了非常简单的演示,从最初的层面说明了这一点。感谢卡梅隆·纽汉的出色表现。
当然啦。实际上,有几个东西的半径比MAXRADIUS(我相信是蜘蛛和蜘蛛)还要大。ID选择不纠正这一点,可能是因为增加MAXRADIUS会导致Doom在碰撞检测方面做更多的工作(虽然与渲染和视线计算等其他任务所花费的时间相比,这项工作微不足道,但对我来说,这似乎是一个奇怪的优化选择)。顺便说一句,这可能解释了为什么当玩家与蜘蛛恶魔相撞时,物理学并不总是感觉正确:MAXRADIUS小于蜘蛛恶魔的半径意味着碰撞检测会让物体比在某些情况下更接近怪物(尽管精灵在游戏中没有占据物体的整个区域可能是对感觉错误的更好的解释)。
我在这里简化一下:Doom实际上并不是首先列出一个列表,它使用一个简单的步进算法(类似于任何读取此列表的计算机图形类型的经典Bresenham线条光栅算法)按顺序遍历这些列表。
除非另有说明,否则本网站版权所有©2011 Colin Phips<;[email protected]>;,并根据Creative Commons Attribution-ShareAlike 2.5许可证进行许可。