C++ 让敌方车辆跟随玩家车辆C++;

C++ 让敌方车辆跟随玩家车辆C++;,c++,artificial-intelligence,C++,Artificial Intelligence,我目前正在制作一个游戏,玩家驾驶一辆半卡车,然后被敌人的汽车跟踪和攻击。我从我的一位老师那里得到了一些帮助,教我如何让敌人选择前进的方向,以便跟随并攻击玩家。在实施了她给我的东西后,我有了奇怪的行为,觉得我错过了什么 当我在游戏中将敌车放在玩家附近,并将玩家的位置传递到函数中时,敌车只会旋转一圈。如果我增加速度,我会在大圆圈里驾驶。一般来说,它从不选择直行方向 在调试之后,我的if语句似乎永远无法解析,每次更新时,它都试图返回0,但由于某些原因,它无法解析。 我不确定玩家的坐标是否造成了问题,或

我目前正在制作一个游戏,玩家驾驶一辆半卡车,然后被敌人的汽车跟踪和攻击。我从我的一位老师那里得到了一些帮助,教我如何让敌人选择前进的方向,以便跟随并攻击玩家。在实施了她给我的东西后,我有了奇怪的行为,觉得我错过了什么

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

在调试之后,我的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() };
}
void EnemySpeedy::playerTracking(float-posX,float-posY)
{
//方向选择
dir.x=posX-pos.x;
dir.y=posY-pos.y;
//再加上这个?
goalAngle=atan2f(方向y,方向x);
//我想这就是问题代码//
如果(角度<目标)角度-=sfw::getDeltaTime()*角度速度;
else angle+=sfw::getDeltaTime()*角速度;
//加速度
acc=速度;
vel=vel+(acc-dragVel)*sfw::getDeltaTime();
vel=std::fmaxf(0,vel);
vel=std::fminf(vel,maxVel);
pos={pos.x+vel*cosf(角度*PI/180)*sfw::getDeltaTime(),
位置y+vel*sinf(角度*PI/180)*sfw::getDeltaTime()};
}

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

我不知道你的
角度
角速度
是否使用相同的度量,但是当你计算
sinf
cosf
时,你正在将
角度
从度转换为弧度

我建议将所有角度保持在弧度,并进行检查:

#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 );
}
#包括
内联浮动法(浮动法){
返回ang<-M_-PI?ang+2.0*M_-PI:(ang>M_-PI?ang-2.0*M_-PI:ang);
}
内联浮点限制值(浮点x、浮点最小值、浮点最大值){
返回xmax?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;
}     
void EnemySpeedy::playerTracking(float-posX,float-posY)
{
//方向选择,pos是敌人速度的成员
float dirX=posX-pos.x;
float dirY=posY-pos.y;
//角度选择;角度、角度速度和角度速度最大值是敌人速度的成员
浮动目标=atan2(dirY,dirX);
浮球半径=诺曼角(角度-门角);
角速度=极限值(-difAngle,-角速度最大值,角速度最大值);
float dt=sfw::getDeltaTime();
角度=诺曼角(角度+dt*角速度);
//更新速度;acc、vel等是EneySpeedy类的成员
//acc=速度;//我觉得很奇怪。。。
//vel=极限值(vel+(acc-dragVel)*dt,0.0,最大值);
//那么:
acc=(迪芳格尔>1.5 | |迪芳格尔<-1.5)?-maxAcc/2.0:maxAcc*(maxVel-vel)/maxVel;
//如果方向错误,则制动,否则转到限制速度
acc=限制值(acc,-maxAcc,maxAcc);
vel=极限值(vel+acc*dt,0.0,最大值);
//更新位置
位置x+=水平*cos(角度)*dt;
位置y+=水平*sin(角度)*dt;
}     

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

我不知道你的
角度
角速度
是否使用相同的度量,但是当你计算
sinf
cosf
时,你正在将
角度
从度转换为弧度

我建议将所有角度保持在弧度,并进行检查:

#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 );
}
#包括
内联浮动法(浮动法){
返回ang<-M_-PI?ang+2.0*M_-PI:(ang>M_-PI?ang-2.0*M_-PI:ang);
}
内联浮点限制值(浮点x、浮点最小值、浮点最大值){
返回xmax?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;
}     
void EnemySpeedy::playerTracking(float-posX,float-posY)
{
//方向选择,pos是敌人速度的成员
float dirX=posX-pos.x;
float dirY=posY-pos.y;
//角度选择;角度、角度速度和角度速度最大值是敌人速度的成员
浮动目标=atan2(dirY,dirX);
浮球半径=诺曼角(角度-门角);
角速度=极限值(-difAngle,-角速度最大值,角速度最大值);
float dt=sfw::getDeltaTime();
角度=诺曼角(角度+dt*角速度);
//更新速度;acc、vel等是EneySpeedy类的成员
//acc=速度;//我觉得很奇怪。。。
//vel=极限值(vel+(acc-dragVel)*dt,0.0,最大值);
//那么:
acc=(迪芳格尔>1.5 | |迪芳格尔<-1.5)?-maxAcc/2.0:maxAcc*(maxVel-vel)/maxVel;
//如果方向错误,则制动,否则转到限制速度
acc=限制值(acc,-maxAcc,maxAcc);
vel=极限值(vel+acc*dt,0.0,最大值);
//更新位置
位置x+=水平*cos(角度)*dt;
位置y+=水平*sin(角度)*dt;
}     

角度是指汽车指向的方向,角速度是指汽车旋转角度的速度。@Andrew C Ward:是的,我算出来了;)。我想知道你是否使用了弧度或度数。这段代码显然工作得更好,至少它现在选择了一个方向并锁定了它。下一个问题是,无论输入如何变化,它总是朝着同一个方向运行。基本上,它不会跟随剧本,但它会不断地选择一些任意点。“有什么想法吗?”安德鲁·C·沃德:奇怪。您确定要传递正确的值吗?EnemySpeedy类的成员是如何初始化的?我假设pos、acc、vel、angle和angularSpeed都是类成员,对吗?@A