边缘生活

过去一周,我和一个同学一起为班级项目创建游戏。 它是我以前玩过的名为Doodle Jump的手机游戏的克隆版本,看起来像这样。

事实证明,游戏中充斥着最常见的编码位置之一,以至于偶然地在逻辑上有所失误:边缘情况。 当算法或系统接受其最极端的输入时,“边缘情况”是一个相当描述性的术语。 正是在流程中的这些关键点上,控制该系统的流程最经常崩溃。 这可能是由于多种因素造成的。 也许程序员只是误解了可接受值的界限,而是写了一个“小于”符号而不是“小于或等于”。 也许机械专家没有正确测试扬声器的外壳,并且在将扬声器调至11的时间过长后,扬声器的外壳开始破裂。

我在编写上述游戏时经历了前者。 我们有一个函数,可以在60帧周期内模拟重力对跳跃化身的影响。 它会跳上30帧,然后掉下30帧,同时检查下行时是否有碰撞,重力在整个过程中均匀地作用。 超过60帧周期,另一个功能处理了我们认为是“自由落体”的行为。 在这一点上,达到了极限速度,并且不再有作用在跳线上的重力。 不幸的是,确定哪个功能应该在什么时候接手的逻辑有点缺陷。 我们进行了设置,以便从第0帧到第59帧负责重力函数。 然后在框架60上方,自由落体功能将控制住。 当然,这意味着恰好在第60帧时,没有人告诉跳投者该怎么做,所以他会无限期地漂浮在那里。

这是不小心处理边缘盒的简单示例。 如果您的算法有时会出现故障或意外副作用,那么这种情况就发生在这些地方。 就我而言,粗心的结果是显而易见的,因此我们能够迅速解决该问题。 但是在其他很多时候,事情可能很难解释。 出于这个原因,我提醒您始终密切注意边缘情况,并确保小心处理它们。 以下是一些严重问题的例子,这些问题已出现在任天堂的《塞尔达传说:时之笛》的制作版本中。 这些示例是售出的每个游戏副本中都存在的故障,如果您知道要查找的内容,则它们执行起来相对简单。 但是不幸的是,对于开发团队来说,他们一开始也很难想象,因此这些故障得以解决。

第一个故障是由玩家命名为“ Infinite Sword Glitch”或ISG的故障。 Link扮演的角色具有多种状态,取决于他执行的操作,他可以​​处于多种状态。 例如,当他挥舞剑时,游戏会激活武器上先前惰性的打击盒,使其与敌人碰撞以造成伤害。 这是做事的聪明方法。 当然,当林克(Link)手里拿着剑跑来跑去时,您并不想一直与之碰撞,并破坏他前进道路上的任何事物。 好吧,这正是您可以做的。 处于“挥剑”状态时,Link不能阅读符号或与其他字符交谈。 通常,在剑击中按下按钮执行此操作绝对没有任何作用。 但是,正如您可能已经猜到的那样,这里没有出现边缘情况。 剑刺的一种特别是刺伤,在攻击的最后一帧,可以弹出一个文本框。 有趣的是,如果攻击能够自然完成,那么游戏也将停用剑的命中框。 因此,通过在此最后动作框上显示一个文本框,永远不会给Hitbox适当地停用,您就可以使用无限破坏性武器来逃避! 酷吧?

下一个例子更加荒谬。 游戏中有一个称为“挂钩”的项目。 它基本上是一个可伸缩的抓钩,可以将链接拉到该钩可以锁定在诸如木质表面上的目标。 在飞向钩状物体的过程中,Link自己的命中盒被停用,使其无敌无敌。 之所以这样做,是因为有一套完全独立的物理方法控制着钩子的状态,这与死亡的可能性并不太相称。 抱歉,这又是一个令人讨厌的极端情况问题,除了这次是在状态更改的开始而不是像ISG示例那样在结束时。 在钩子与可钩对象连接的第一帧上,Link的命中盒仍然处于活动状态,并且仍然能够承受伤害。 如果在此帧上将他的生命值降低到0,他将会死亡。 除了他也刚刚开始飞向那钩住的物体。 事实证明,在挂钩物体的第一帧上,Link被赋予了惊人的垂直速度以使他迅速离开地面。 通常这很好,因为在玩家不再具有直接控制权的时间内,速度会很快消除。 但是,既然Link意外死亡,那么就可以按照自己的意愿随意采取行动。

故事的寓意:小心手边的箱子,否则您可能会发现自己身着发光的死亡之剑在3万英尺高空飞行。