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