C# AI敌人在追击玩家的同时互相聚集

C# AI敌人在追击玩家的同时互相聚集,c#,xna,artificial-intelligence,xna-4.0,path-finding,C#,Xna,Artificial Intelligence,Xna 4.0,Path Finding,我创造了一些敌人,在游戏中追逐玩家,但是有一个问题。敌人太完美了,当他们接近玩家时,他们会很快会聚在一起。这是因为每次游戏更新时,它们只是朝着玩家的方向移动 我想给敌人引入一些随机性,可能是运动角度。这就是我到目前为止所做的(我还没有对它进行优化,因为它还没有完成,所以我知道开销很高): 如果我尝试向角度添加一个随机数,则会出现两个问题: 它们彼此更新得如此之快,以至于它们的种子时间都是相同的 在每次更新中,随机数是如此的不同,以至于敌人的角度不稳定地跳跃 所以我想知道的是:大多数游戏是如何解决

我创造了一些敌人,在游戏中追逐玩家,但是有一个问题。敌人太完美了,当他们接近玩家时,他们会很快会聚在一起。这是因为每次游戏更新时,它们只是朝着玩家的方向移动

我想给敌人引入一些随机性,可能是运动角度。这就是我到目前为止所做的(我还没有对它进行优化,因为它还没有完成,所以我知道开销很高):

如果我尝试向角度添加一个随机数,则会出现两个问题:

  • 它们彼此更新得如此之快,以至于它们的种子时间都是相同的

  • 在每次更新中,随机数是如此的不同,以至于敌人的角度不稳定地跳跃

  • 所以我想知道的是:大多数游戏是如何解决这个问题的?我应该如何让敌人选择不同的路径(而不需要访问其他敌人的列表)

    编辑:

    以下是我对未来路人的建议后使用的代码:

    Angle = (float)Math.Atan2((HeroPosition - Position).Y, (HeroPosition - Position).X);
    GlobalForce Propellant = new GlobalForce((float)Math.Cos(Angle) / 2, (float)Math.Sin(Angle) / 2);
    ApplyForce(Propellant);
    
    foreach (Enemy e in OtherEnemies)
    {
        if (e != this)
        {
            if ((e.Position - Position).Length() < 64)
            {
                float angleBetween = MathHelper.TwoPi-(float)Math.Atan2((e.Position-Position).Y, (e.Position-Position).X);
                GlobalForce avoidance = new GlobalForce((float)Math.Cos(angleBetween)*2, (float)Math.Sin(angleBetween)*2);
                ApplyForce(avoidance);
            }
        }
    }
    
    Angle=(float)Math.Atan2((HeroPosition-Position).Y,(HeroPosition-Position.X);
    GlobalForce推进剂=新的GlobalForce((浮动)数学Cos(角度)/2,(浮动)数学Sin(角度)/2);
    应用力(推进剂);
    foreach(其他敌人中的敌人e)
    {
    如果(e!=这个)
    {
    if((e.Position-Position).Length()<64)
    {
    float angleBetween=MathHelper.TwoPi-(float)Math.Atan2((e.Position-Position).Y,(e.Position-Position).X);
    全局力回避=新全局力((浮点)数学Cos(angleBetween)*2,(浮点)数学Sin(angleBetween)*2);
    申请强制(回避);
    }
    }
    }
    
    大多数游戏都是通过让敌人互相阻挡来避免这种情况,这样他们就不会移动到同一个空间


    这可以作为硬约束(例如,每个方格中只允许一个敌人,其他敌人不能进入已被占领的方格)或软约束(如果敌人过于靠近,一些隐藏的“力量”会将他们推开)。

    AI战术的重要部分(以及人类战术BTW)不仅要知道敌人在哪里并采取行动,还要知道盟友在哪里并采取行动。没有这一点,大多数最简单和最著名的演习都是不可能的(想想包围)

    这在很大程度上归结为“如果你能避免的话,不要太接近盟友”


    因此,基本上你需要做的是以一种方式管理你的部队,让它不仅被敌人吸引,而且被盟友拒绝(不太可能)。结合两级寻路器,你就完成了。

    去年,我不得不为我参加的一门课程编写一个吃豆人游戏

    我用这个来对付敌人

    直接运行此算法将产生完美的敌人


    诀窍是给算法的结果增加一些随机性——当难度降低时,让敌人“犯错误”(即,去一个与算法产生的方向不同的方向,当难度降低时,敌人会犯更多的“错误”)

    中间解决方案是针对不同的AI采用不同的策略。e、 g.一个AI定位玩家现在所在的位置,另一个AI定位玩家要去的位置,另一个AI习惯性地尝试在玩家以南悬挂几个单位,除非玩家直接移动


    这不如制定一个策略,让你的AI考虑到他们的朋友在哪里,但是(如果写得正确的话)这会让他们表现得不同。

    如果每个敌人都是独立的,并且无法进入任何其他敌人的阵地,那该怎么办?为什么他们无法进入?您应该能够让他们访问此数据。。。。也许是通过搜索周围地图区域的“findNearbyUnits()”方法。我现在决定在更新方法中传递一个对敌人列表的引用,并计算他们之间的角度,然后创建一个力,如果他们太近,将他们推开听起来不错。尽管考虑将敌人列表放入某种传递给更新方法的全局“游戏状态”对象中。这样,您不仅可以通过该对象访问敌人列表,还可以访问其他各种数据。从长远来看,这将避免您传递大量参数……对于大多数项目来说都是一个好主意,但在这种情况下,这是这些敌人唯一需要的。不过,感谢你的建议:)看起来我必须给每个实例一个敌人列表的参考,毕竟要避开盟友:)这取决于你的使用情况:我怀疑你的角色会有某种检测范围,所以你可以将检测到的盟友用作推送提供者。我认为,这将是一个相当现实的运动模式。这是一个有用的想法,但不幸的是,我已经在使用转向行为
    Angle = (float)Math.Atan2((HeroPosition - Position).Y, (HeroPosition - Position).X);
    GlobalForce Propellant = new GlobalForce((float)Math.Cos(Angle) / 2, (float)Math.Sin(Angle) / 2);
    ApplyForce(Propellant);
    
    foreach (Enemy e in OtherEnemies)
    {
        if (e != this)
        {
            if ((e.Position - Position).Length() < 64)
            {
                float angleBetween = MathHelper.TwoPi-(float)Math.Atan2((e.Position-Position).Y, (e.Position-Position).X);
                GlobalForce avoidance = new GlobalForce((float)Math.Cos(angleBetween)*2, (float)Math.Sin(angleBetween)*2);
                ApplyForce(avoidance);
            }
        }
    }