【问题标题】:Getting enemy vehicle to follow player vehicle C++让敌方车辆跟随玩家车辆 C++
【发布时间】:2015-11-24 19:49:30
【问题描述】:

我目前正在构建一个游戏,玩家驾驶一辆半卡车,然后被敌方汽车尾随并尝试猛烈撞击。我从我的一位老师那里得到了一些帮助,教我如何让敌人选择前进的方向,以便跟随并攻击玩家。在实施她给我的东西后,我的行为很奇怪,感觉好像我错过了一些东西。

当我在游戏中将一辆敌车放置在玩家附近并将玩家的位置传递到函数中时,敌车只会在圆圈中旋转。如果我向它添加速度,我会在大圆圈中行驶。一般来说,它从不选择直行的方向。

在调试之后,我的 if 语句似乎永远无法解析,并且在每次更新时它一直试图回到 0,但由于某种原因它不能。 我不确定是玩家的坐标造成了问题,还是我的数学计算出了问题。

void EnemySpeedy::playerTracking(float posX, float posY)
{
    //Direction choosing
    dir.x = posX - pos.x;
    dir.y = posY - pos.y;

    //plus maybe this?
    goalAngle = atan2f(dir.y, dir.x);

    //I think this is the problem code?//
    if (angle < goalAngle) angle -= sfw::getDeltaTime() * angularSpeed;
    else                   angle += sfw::getDeltaTime() * angularSpeed;


    //AI Movement alla adding velocity
    acc = speed;

    vel = vel + (acc - dragVel) * sfw::getDeltaTime();

    vel = std::fmaxf(0, vel);
    vel = std::fminf(vel, maxVel);

    pos = { pos.x + vel * cosf(angle * PI / 180) * sfw::getDeltaTime(),
            pos.y + vel * sinf(angle * PI / 180) * sfw::getDeltaTime() };
}

【问题讨论】:

标签: c++ artificial-intelligence


【解决方案1】:

atan2f 返回弧度,因此您的 goalAngle 在 [-Pi,Pi] 范围内。

我不知道您的angleangularSpeed 是否使用相同的度量标准,但是当您计算sinfcosf 时,您正在将angle 从度数转换为弧度。

我建议将所有角度保持在弧度并检查它们:

#include <cmath>

inline float normAngle ( float ang ) {
    return ang < -M_PI ? ang + 2.0*M_PI : ( ang > M_PI ? ang - 2.0*M_PI : ang);
}

inline float limitValue ( float x, float min, float max ) {
    return x < min ? min : ( x > max ? max : x );
}

那么,你可以试试这个逻辑:

void EnemySpeedy::playerTracking(float posX, float posY)
{
    //Direction choosing, pos is a member of EnemySpeedy
    float dirX = posX - pos.x;
    float dirY = posY - pos.y;

    //Angle choosing; angle, angularSpeed and angularSpeedMax are members of EnemySpeedy
    float goalAngle = atan2(dirY, dirX);
    float difAngle = normAngle(angle - goalAngle);
    angularSpeed = limitValue(-difAngle,-angularSpeedMax,angularSpeedMax);
    float dt = sfw::getDeltaTime();
    angle = normAngle(angle + dt * angularSpeed);

    // Update speed; acc, vel, etc. are members of EnemySpeedy class
    // acc = speed;         // it seems odd to me...
    // vel = limitValue(vel + (acc - dragVel) * dt, 0.0, maxVel);
                         // what about:
    acc = (difAngle > 1.5 || difAngle < -1.5) ? -maxAcc/2.0 : maxAcc*(maxVel - vel)/maxVel;
    //          brake if direction is wrong, go to limit velocity otherwise
    acc = limitValue(acc, -maxAcc, maxAcc);
    vel = limitValue(vel + acc * dt, 0.0, maxVel);

    // Update position
    pos.x += vel * cos(angle) * dt;
    pos.y += vel * sin(angle) * dt;
}     

【讨论】:

  • 角度是汽车指向的方向,角速度是它旋转角度的速度。
  • @Andrew C Ward:是的,我想通了;)。我想知道您使用的是弧度还是度数。
  • 这段代码显然工作得更好,它至少现在选择了一个方向并锁定它。下一个问题是,无论输入如何变化,它总是朝着同一个方向发展。基本上它不会跟随游戏,而是不断选择一些任意点。有什么想法吗?
  • @Andrew C Ward:奇怪。您确定传递正确的值吗? EnemySpeedy 类的成员是如何初始化的?我假设 pos、acc、vel、angle 和 angularSpeed 都是类成员,对吗?
  • @Andrew C Ward:它选择哪个方向?
猜你喜欢
  • 1970-01-01
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多