来自程序员的透视(2015)的兔子

2021-06-05 15:54:43

" Bunnyhopping"在Quake III竞技场,半衰期和反击等游戏中是一种非常受欢迎的错误。 Bunnyhopping或Bhopping for Short,允许玩家超过游戏定义的速度限制。它创建了完全新的播放方法,并允许非常令人兴奋,快节奏的紧急游戏。作为一个明确的技巧的机械师,竞争球员喜欢Bhopping,因为它很难掌握。因此,您作为游戏开发人员对"实施" Bunnyhopping进入你的游戏。本文的目的是定义Bunnyhopping的原因,为什么考虑作为游戏开发人员很重要,以及如何在数学上将其实施到您的FPS移动代码中。所有代码示例都是开源的,始终是免费的。

Bunnyhopping最重要的成分是空气流动的概念。在上面的剪辑中,您可能会注意到玩家迅速掀起鼠标左右。当他这样做时,他用他的运动钥匙同步他的鼠标运动。也就是说,当他将鼠标移动到左侧时,他握住了一个(左移)键,当他将鼠标移动到右侧时,他握住D(右移)键。来自玩家的结果和#39; S的透视是速度快速增加。这部分地解释了为什么Bunnyhopping是这样一种技能的机械师。它需要很大的技巧和准确性,可以将您的鼠标移动与移动钥匙完美地同步。

由于在地震引擎中处理移动加速度的方式,空气流放工作。在任何基于地震引擎的游戏中可以进行,例如源。如果您希望您可以查看Quake III运动代码或GitHub上的半衰期2机芯代码。请记住,两个代码库都包含特定于发动机的代码,因此它们是易于集成在本文中的代码中的易于集成。然而,看到机械师的起源仍然有趣。

在Quake III加速码中,运动速度以非常有趣和极性的方式受到限制。代替直接限制速度,而不是限制电流速度在加速度上的投影是有限的。要进一步解释这一点,我需要首先解释矢量投影。

向量A投影到载体B上(也称为A的组分)是" A在平行于B&#34的直线上的orthagonlople投影; (引用维基百科)。这个概念如下所示。

v proj = | a | * COS(θ)= A•B上方,表示点产品,B是B的单位向量(即,B的方向的载体和1)。 DOT产品符号为代表产品等于| A | * | B | * cos(θ)。这是优选的,因为它比余弦计算更快。

我之前的说法我在这里重复了什么:代替直接限制速度,而是仅将当前速度的投影限制在加速度上。这允许玩家超过某些情况下的最大速度。回想一下,为了机架式机构,您必须使用鼠标移动同步移动键。在数学上设'

图2:使用投影限制速度。 "时间0"在左上角,时间1在右上角等。以下是该图的关键:V C =在任何计算之前的当前速度V W =玩家想要进入的方向(所谓的希望方向)。 v p = v c投射到V w。请记住,我们只考虑该计算中的幅度,因此投影的方向并不是。 v a =要添加到v p的加速度。此加速度的大小是定义的。 v max =服务器定义的最大速度。如果V P + V A超过此,则截断V a。

在上面的示例中,播放器既移动并左转。 4个物理刻度后,v P通过服务器定义的速度限制v max,v a被截断以占此帐户。但请注意,V C仍然大大超过V Max!

私有Vector3加速(Vector3 Accell,Vector3 Previpity,Float Accelerate,Float Max_velocity){Float Projvel = Vector3。 DOT(Previpity,Accell); //当前速度的矢量投影到Accell。 Float Accelvel =加速*时间。固定地德拉斯省; //加速速度在移动方向//如有必要,截断加速速度,使矢量投影不超过max_velocity(projvel + Accelvel> max_velocity)Accelvel = max_velocity - projvel;返回PreviLocity + Acceldir * Accelvel; }

摩擦还在兔子普通以及一般的地震风格中起着重要作用。 Bunnyhopping赢得了它的名字,因为玩家实际上必须跳跃以获得速度。这是因为如果玩家没有做这种摩擦会降低速度。

那么,为什么,它是可能的兔子? WORN' T你总是击中地面,从而失去速度?这实际上在地震或源引擎中不是真的,因为有一个1帧窗口,当玩家击中地面时不应用摩擦。这意味着玩家有一个帧来输入跳转命令而不会丢失速度 - 这是熊尼霍普上很难的另一个原因!如果您想保留Bunnyhopping的技能性质,请务必将此延迟添加到您的物理计算中。如果您希望Bhopping可以访问新玩家,您可以添加播放器可以简单地保持空间以自动跳过框架的自动bhopping。

浮动速度= previpity。震级 ; if(速度!= 0)//避免归零误差{float drop = speed *摩擦*时间。固定地德拉斯省; previvelocity * = mathf。最大(速度 - 滴,0)/速度; //根据摩擦缩放速度。 }

当然,摩擦力仅在玩家接地时应用。摩擦是近似范围1-5的服务器定义变量。摩擦较高,表面较少。如果您熟悉源引擎中的控制台命令,则可以将此变量识别为SV_FRICTION。

// Acceldir:归一化方向,播放器已要求移动(考虑到移动键和看方向)// previpity:玩家的当前速度,在任何额外的计算//加速:服务器定义播放器加速度// MAX_VELOCITY:服务器定义的最大播放器速度(这不是由于StradeJumping的严格遵守)私有Vector3加速(Vector3 Accell,Vector3 PreviCity,Float Accelerate,Float Max_velocity){Float Projvel = Vector3。 DOT(Previpity,Accell); //当前速度的矢量投影到Accell。 Float Accelvel =加速*时间。固定地德拉斯省; //加速速度在移动方向//如有必要,截断加速速度,使矢量投影不超过max_velocity(projvel + Accelvel> max_velocity)Accelvel = max_velocity - projvel;返回PreviLocity + Acceldir * Accelvel;私人Vector3 Leveground(Vector3 Accell,Vector3 PreviLocity){//应用摩擦浮动速度= PrevIpocity。震级 ; if(速度!= 0)//避免归零误差{float drop = speed *摩擦*时间。固定地德拉斯省; previvelocity * = mathf。最大(速度 - 滴,0)/速度; //根据摩擦缩放速度。 } // ground_accelerate和max_velocity_ground是服务器定义的移动变量返回加速(acceldir,previbity,ground_accelerate,max_velocity_ground);私人Vector3 MoveAir(Vector3 Accell,Vector3 PreviLocity){// air_Accelerty和Max_Velocity_Air是服务器定义的移动变量返回加速(Acceldir,PreviCity,Air_Accelerate,MAX_Velocity_Air); }

熟悉源引擎的人可能再次识别此代码中的SV_ACCELETE,SV_AIRACCELATE和SV_FRICTION SCRARAR。花一些时间来调整这些服务器定义的变量,因为它们决定了游戏的感觉'运动。

它'它!这应该是所有你需要在你的游戏中实施兔子。如果您有任何疑问或意见,请随时在以下意见部分发布。谢谢你的阅读!

Quake III运动代码 - 这是&#34的原始地震引擎的移动代码;启动它所有"在怀旧中检查一下。那里有很多发动机特定/杂乱的代码所以注意。

源引擎移动代码 - 此代码基于Quake引擎代码。然而,解读的比Quake引擎更容易。它还来自未发布的TF2&#34的旧代码;指挥官模式"这很酷。

"我如何实施streaf-跳跃?" - 这是一个GameVevStackexchange问​​题,它在StradeJumping背后的数学上非常启发。

F3Quake - Strafing理论 - 这是一个关于STRAFE跳跃的玩家创作的数学分析,寻求找到数学上最佳的空气磨削策略。它'对于任何数学书呆子的有趣阅读。它还详细介绍了为硬核社区缘故实施兔子。

评论由Disqus提供动力