如何为RPG升级要求创建可调公式?


44

我正在尝试创建一个可以简单地通过更改两个值来修改的公式:number_of_levels和last_level_experience。这是为了使人们能够改变游戏的水平要求。

我已经知道了,以便可以指定上一级升级所需的XP数量,但是我希望能够控制上一级升级所需的XP,在这种情况下,它们可能会有很大差异。例如,如果我有40个等级,最后一个等级为1,000,000 XP,则第一个等级要求为625。但是,如果我将等级更改为80,则第一个等级变为156。在两种情况下,最后一个等级都需要1,000,000。

仅通过这两个基本值,就必须有某种方法使计算机绘制出合适的曲线。

#include <iostream>

int main()
{
    int levels = 40;
    if (levels < 2) levels = 2;

    int experience_for_last_level = 1e6;
    float fraction = 1.0 / levels;

    {
        int i = 0;
        float fraction_counter = fraction;
        int counter = levels;
        int total = 0;

        for (i = 1; i <= levels; ++i, fraction_counter += fraction, --counter)
        {
            int a = static_cast<int>(fraction_counter * experience_for_last_level / counter);

            std::cout <<"Level "<<i<<":  "<<a<<" ("<<counter<<")"<<"\n";

            total += a;
        }

        std::cout << "\nTotal Exp: " << total;
    }
}

输出:

Level 1:  625   (40)      Level 15: 14423  (26)      Level 29: 60416  (12)
Level 2:  1282  (39)      Level 16: 16000  (25)      Level 30: 68181  (11)
Level 3:  1973  (38)      Level 17: 17708  (24)      Level 31: 77499  (10)
Level 4:  2702  (37)      Level 18: 19565  (23)      Level 32: 88888  (9)
Level 5:  3472  (36)      Level 19: 21590  (22)      Level 33: 103124 (8)
Level 6:  4285  (35)      Level 20: 23809  (21)      Level 34: 121428 (7)
Level 7:  5147  (34)      Level 21: 26250  (20)      Level 35: 145833 (6)
Level 8:  6060  (33)      Level 22: 28947  (19)      Level 36: 179999 (5)
Level 9:  7031  (32)      Level 23: 31944  (18)      Level 37: 231249 (4)
Level 10: 8064  (31)      Level 24: 35294  (17)      Level 38: 316666 (3)
Level 11: 9166  (30)      Level 25: 39062  (16)      Level 39: 487499 (2)
Level 12: 10344 (29)      Level 26: 43333  (15)      Level 40: 999999 (1)
Level 13: 11607 (28)      Level 27: 48214  (14)
Level 14: 12962 (27)      Level 28: 53846  (13)

13
根本的问题是,有无限多的XP等级曲线会以需要那么多XP的最后一个等级结束。您尚未限制问题的范围,因为尚未说明希望XP 如何逐级更改。您想要指数增长曲线吗?抛物线的增长曲线?线性的?您的问题在当前状态下无法解决。就个人而言,如果我要修改游戏,我希望对XP曲线的控制更多,而不仅仅是最后一级和最后一级的XP。我想控制实际曲线本身。
Nicol Bolas

我可以允许修改者通过脚本控制调平。
权杖

Answers:


71

尽管有无数种选择方法,但调平曲线通常遵循如下幂规则

f(level) == A * exp(B * level)

该公式的主要优点很容易解释:对于给定的规则,存在一个固定值N,使得每个级别的成本比上一个级别高N%

您的初始变量添加了以下限制:

f(1) - f(0) == experience_for_first_level
f(levels) - f(levels - 1) == experience_for_last_level

两个方程,两个未知数。看起来不错 简单的数学给出AB

B = log(experience_for_last_level / experience_for_first_level) / (levels - 1);
A = experience_for_first_level / (exp(B) - 1);

产生以下代码:

#include <cmath>
#include <iostream>

int main(void)
{
    int levels = 40;
    int xp_for_first_level = 1000;
    int xp_for_last_level = 1000000;

    double B = log((double)xp_for_last_level / xp_for_first_level) / (levels - 1);
    double A = (double)xp_for_first_level / (exp(B) - 1.0);

    for (int i = 1; i <= levels; i++)
    {
        int old_xp = round(A * exp(B * (i - 1)));
        int new_xp = round(A * exp(B * i));
        std::cout << i << " " << (new_xp - old_xp) << std::endl;
    }
}

和以下输出:

1 1000          9 4125          17 17012        25 70170        33 289427
2 1193          10 4924         18 20309        26 83768        34 345511
3 1425          11 5878         19 24245        27 100000       35 412462
4 1702          12 7017         20 28943        28 119378       36 492389
5 2031          13 8377         21 34551        29 142510       37 587801
6 2424          14 10000        22 41246        30 170125       38 701704
7 2894          15 11938        23 49239        31 203092       39 837678
8 3455          16 14251        24 58780        32 242446       40 1000000

12
如果所有的答案都经过精心计划和考虑。
Nate

这里的曲线更可口。
Truncheon

好答案。这可能是一个愚蠢的问题,但是如何计算N上述的呢?如果要设置N可插拔变量该怎么办?让我知道是否应该为此提出一个单独的问题。
丹尼尔·卡普兰

1
@tieTYT的关系之间NBexp(B) = 1 + NB = log(1 + N)。所以,如果你想每个级别需要例如 15%以上,比以前的一个,你需要B = log(1 + 0.15) = 0.13976
sam hocevar

18

弄清楚曲线后,别忘了将数字四舍五入。告诉玩家他需要119,378点经验值才能达到下一个水平,这没有多大意义-因为这个人总是将其理解为“大约120,000”。因此,您最好自己四舍五入,并向您的玩家展示“干净”的结果。例如,以下代码(在Sam Hocevar的基础上扩展)将尝试舍入到≈2.2个有效数字(显然,可以根据需要调整常数):

from math import exp, log

levels = 40
xp_for_first_level = 1000
xp_for_last_level = 1000000

B = log(1.0 * xp_for_last_level / xp_for_first_level) / (levels - 1)
A = 1.0 * xp_for_first_level / (exp(B) - 1.0)

def xp_for_level(i):
    x = int(A * exp(B * i))
    y = 10**int(log(x) / log(10) - 2.2)
    return int(x / y) * y

for i in range(1, levels+1):
    print( "%d:  %d" % (i, xp_for_level(i) - xp_for_level(i-1)) )

输出为:

1:  1000     9:  4200     17:  17100    25:  70000     33:  287000
2:  1190    10:  4900     18:  20300    26:  84000     34:  340000
3:  1420    11:  5900     19:  24200    27:  100000    35:  420000
4:  1710    12:  7000     20:  28700    28:  119000    36:  490000
5:  2030    13:  8400     21:  34000    29:  142000    37:  590000
6:  2420    14:  10000    22:  42000    30:  171000    38:  700000
7:  2870    15:  11900    23:  49000    31:  203000    39:  840000
8:  3400    16:  14200    24:  59000    32:  242000    40:  1000000
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.