Unity3D关于随机生成敌人的分级算法

问题:

假设我有10种敌人,一共20关,每关3-5个敌人就可以满足我的关卡难度,那么怎么随机生成每关的敌人,使每一关的敌人尽量都不一样同时难度递增呢?

1.生成敌人个数曲线:

    如果3-5个敌人就可以满足关卡难度那么每多一个敌人,难度就是成倍增加的,所以随着关卡数上升,敌人个数不能线性增长,可以对数增长,即

敌人数基数 ={_{}}^{}log^{a} 关卡数

但是这样第一关不就生成0个敌人?所以应该还要加上一个初始基数

敌人数基数y ={_{}}^{}log^{a} 关卡数x +初始基数

敌人的实际数量在这个基数上随机波动,范围要根据实际情况自定,同时应该定一个上限,即最高可以生成多少敌人。最好到达19或者20关时刚好基数到达上限

假设同时打8个敌人就是最高上限

a=x的y分之一次方,a=(8-4)^{1/20}=2.11

int MaxSpownNumber=8;
int BaseSpownNubmer=4;
int SpownNubmerDownFloat=1;//向下波动1
int SpownNubmerUpFloat=1;  //向上波动1

float a = Mathf.Pow((float)MaxSpownNumber, 1f / Level);
int mBaseSpownCount = Mathf.Min(Mathf.FloorToInt(Mathf.Log(a, CurrentLevel)) + BaseSpownNumber, MaxSpownNumber);
int SpownNumber = Random.Range(mBaseSpownCount - SpownNumberDownFloat, mBaseSpownCount + SpownNumberUpFloat);

2.敌人难度分级

将所有的敌人依照难度分级,敌人拥有难度因子变量d

初始容易关卡不应该有难度因子高的敌人。可以有一个可生成种类设置Count,可以试试与关卡数成线性

Count=a*TotalLevel,若总共有10种,开始关可以生成四种,20关,

Count=0.3*TotalLevel;

int BaseSpownCount=4;
int Level=20;
int CurrentLevel

//返回当前这一关可以生成的种类数
private int GetSpownTypeCountWithLine()
{
    int count = 0;
    count =Mathf.CeilToInt ((float)(enemys.Count - BaseSpownCount) / Level * CurrentLevel);
    if (count > enemys.Count)
    {
        count = enemys.Count;
    }
    return count;
}

随机生成一个敌人,根据其难度因子d,难度因子越高,生成的机率就越小。

每个敌人的生成机率不同,但所有敌人的生成机率相加为1,使用0-1的随机数就可以确定生成的敌人

如下图所示

也可以不为1,只要保证在算法的处理上可以按难度因子的比率生成对应敌人即可

在生成一个敌人之后,为了尽量不生成第二个,可以将这个敌人生成的机率降为0,同时提高其它的敌人的生成机率

使用数组probability[] 保存所有敌人的生成机率

使用enemys[]保存敌人的prefab,

使用diff[]设置敌人的难度困子,也是初始的生成机率

GetSpownIndex方法根据当前的生成机率随机生成Index,通过index对应生成敌人


public float[] EnemyDiffs;  //设置 
private float[] probabilitys;
private int Count=GetSpownTypeCountWithLine();

private void Start()
{
    for(int i=0;i<enmeys.Count;i++)
    {
        probabilitys[i] = EnemyDiffs[i];
    }
}
private int GetSpownIndex()
{
    int index = 0;
    float total = 0;   //将机率相加
    for (int i = 0; i < Count; i++)
    {
        
        total += probabilitys[i];
    }
    float value = Random.Range(0,total);
    while (value>=0)
    {
        value -= probabilitys[index];
        index++;
        if (index == mSpownTypeCount)
        {
            break;
        }
    }
    return index-1;
}

获得当前要生成的敌人,生成之,然后改变probabilitys

private void ResetProbabilitys(int index)
{
    for (int i = 0; i < Count; i++)
    {
        if (i != index)
            probabilitys[i] += probabilitys[index] / (Count - 1);
    }
    probabilitys[index] = 0;
}

这样每次生成敌人调用如下代码

int spownIndex = GetSpownIndex();
ResetProbabilitys(spownIndex);
GameObject enemyGo = Instantiate(EnemyPrefabs[spownIndex]);

猜你喜欢

转载自blog.csdn.net/QQ734821120/article/details/87364470