战斗数值

5 阅读2分钟

1. 从最基础的式子开始

从最简的原型开始,比较两个数的大小。有两种比较方法:
减法

ABA \ge B

等式左右两边同时减去B得:

AB0A-B \ge 0

除法

ABA \ge B

等式左右两边同时除以B得:

AB1\frac{A}{B} \ge 1

2. 代入

2.1. 减法

在减法中,A可以代入攻击方的攻击Atk,B可以代入防御方的防御Def,其结果可以不再是0,而是具体的伤害值Dmg,有:

AtkDef=DmgAtk - Def = Dmg

这里会存在一种例外情况,当Def大于Atk时,Dmg会呈现负数。所以要包一个外层逻辑:

Dmg = Atk - Def;
Dmg = Mathf.Max(1.0, Dmg); // 保底伤害为1,在1和伤害两值中取大值

currentHp -= Dmg; 
currentHp = Mathf.Clamp(currentHp, 0, maxHp); // 在0和maxHp中取currentHp 
  1. 一般用于TCG卡牌,或者一些小值的计算中。
  2. 减法优势在于玩家可以相当直观的看到数值成长后的等效结果,比如攻击提升1,伤害提升1。这在于玩家养成角色的时候,可以有很直接的养成方向。
  3. 在大值的情况下,Dmg增长可能就不明显。

2.2. 除法

在除法中,同理有:

AtkDef=Dmg\frac{Atk}{Def} = Dmg

在上面的情况下,当Atk和Def相差过大时,实际上是不可用,Dmg会在很大的范围内震荡(0,+\infty),且无法估算预期值。且在Def为0时,会遇到0不可做除数的问题。

如果只是为了解除Def为0的零除问题,解决思路是:

AtkDef+1\frac{Atk}{Def+1}

在上面的基础延申思路,如果数值是小值,Def上限、中值或者小值可以预期,那么直接加入分母也是可行的:

AtkDefmaxDefDefmaxAtk\frac{Def_{max}-Def}{Def_{max}}

上面这个式子也可以写作:

Atk(1DefDefmax)Atk(1-\frac{Def}{Def_{max}})

也可以完全换个符合除法意义的思路(归一化),研究Atk在(Atk+Def)中的占比:

AtkAtk+Def\frac{Atk}{Atk+Def}

此时得到的就是一个比值,再乘以Atk,就可以得到一个可以运用的伤害:

AtkAtkAtk+Def=DmgAtk*\frac{Atk}{Atk+Def} = Dmg

我们可以观察几个特殊情况,来判断是不是真的可以实际运用(这个方法也可以用在其他公式中判断):

① 当Atk=0时,Dmg=0;

② 当Def=0时,Dmg=Atk;

③ 当Atk=Def时,Dmg=12AtkDmg=\frac{1}{2} Atk,其中AtkAtk+Def=12\frac{Atk}{Atk+Def}=\frac{1}{2}

为了让结果更符合\frac{A}{B} \ge 1的情况,所以再乘以一个2:

2Atk2Atk+Def=Dmg\frac{2*Atk^2}{Atk+Def}=Dmg

在这个公式中有以下结论:

  1. 当Atk=Def时,Dmg=Atk;
  2. Atk越大,AtkAtk+Def\frac{Atk}{Atk+Def}越接近1(但不等于1);
  3. Def越大,AtkAtk+Def\frac{Atk}{Atk+Def}越接近0(当不等于0)。

在这个公式当中,如果Atk和Def成长是按等比增长,且Atk大于Def一定等级,那么Dmg可能会增长过快。这也就是WOW当中,一方大于另一方6级,就视为骷髅(难以挑战)的原因。所以适用于专注一定等级范围内挑战平衡的场合。同时,加攻带来的收益显然高于加防带来的收益。

2.3. 其他

如果有更完整的设计前置条件,那么公式也可以进行变化,比如宝可梦公式,核心思路还是最简的AB\frac{A}{B},但将系数的处理用更复杂的形式进行处理:

伤害=((2×L5+2)×P×A50×D+2)×MM=T×W×C×R×S×E×B×O符号说明(基础项)\begin{align*} \text{伤害} &= \left\lfloor \left( \frac{\left(\dfrac{2 \times L}{5} + 2\right) \times P \times A}{50 \times D} + 2 \right) \times M \right\rfloor \\[6pt] M &= T \times W \times C \times R \times S \times E \times B \times O \end{align*} **符号说明(基础项)**
  1. L:攻击方宝可梦等级(1~100)
  2. P:招式基础威力
  3. A:攻击面板(物理 = 攻击,特殊 = 特攻,含强化弱化阶级)
  4. D:防御面板(物理 = 防御,特殊 = 特防,含强化弱化阶级)
  5. 向下取整,每一步计算后都舍去小数

其中M:

符号名称倍率规则
T目标数双打多目标 = 0.75,单体 = 1
W天气晴天火 / 雨天水 = 1.5;晴天水 / 雨天火 = 0.5;其余 1
C暴击暴击 = 1.5,普通 = 1
R随机浮动85%100% 离散取值(0.851.0)
SSTAB 本系加成招式属性与自身属性一致 = 1.5,否则 1
E属性相性抵抗 0.5 / 普通 1 / 克制 2;双属性相乘(如水打岩 = 0.5×2=1)
B灼伤物攻手灼伤 = 0.5,其余 1
O其他修正道具、特性、场地、光墙 / 反射、太晶、Z 招式等所有额外乘区

所有类似公式的设计,都要遵循:

  1. 结果不为负数;
  2. 结果不零除;
  3. 攻防相等的情况下,公式设计的攻防比考虑等于1;
  4. 需考虑成长的伤害波动符合预期等级范围;

3. 属性

3.1. 对抗属性

这里引入一个概念,对抗数值。比如攻击:防御,命中:闪避……
注意,HP比较特殊,它的对抗属性不是攻击,也不是伤害,没有对抗属性。
出现在最简化后的公式里,左边的两个属性就是一对对抗属性。
有时也拿攻防双方的等级作为一对对抗属性。
有部分游戏因为对抗属性比较多,且重要性大于基础攻防,所以会有多个地位相等对抗属性参与计算伤害。

3.2. 属性分级

部分情况下,会对属性进行分级:

  1. 不出现在公式里的,称为基础属性,大多数时候会随着等级成长;
  2. 出现在公式里的,由基础属性换算过来的,称为一级属性;
  3. 出现在公式里,但仅随着部分稀有成就或装备变化的属性,有时也被称为二级属性;
  4. 出现在公式里,可以被展开成一个更复杂公式的部分,现在多数情况下被称为乘区(因为主公式多数为乘法);
  5. 攻防双方等级在部分情况下,也作为对抗属性。

3.3. 属性成长

基础属性的成长基本就只有三种形式,等差、等比和指数。
玩家直觉中,要么每级成长一致,要么每级比上一级增长得多。
如果有需要做边际递减,则应该考虑在基础属性转化为一级属性时处理。

3.3.1. 等差成长

an+1=an+da_{n+1}=a_n+d

每个等级增加固定的数值。

  1. 适合自由加点;
  2. 适合小值(Rogue-Like);
  3. 追求直观增长。

3.3.2. 等比成长

an+1=Aanqa_{n+1} = Aa_n q

每个等级乘以固定的比例。

  1. 适合大值成长;
  2. 等级相差较大时,很容易导致碾压;
  3. 如果想避免碾压,可以考虑在基础属性转化为一级属性时,使用对数函数。

3.3.3. 指数成长

an=Axn1a_n = Ax^{n-1}

每个等级乘以固定的比例。

  1. 适合超大值成长;
  2. 等级差一级,效果相差巨大;