我想获得一些关于我如何制作AI的见解,它可以在地图上平滑地行走(在窗口大小之间)。就像,如果AI到达那个定义的地方,那么它将走到另一个地方。 这是我尝试过的,
首先,我得到一个0.0f到608.0f的随机浮点数,因为我的窗口大小是640,640。
void AIntelligence::GenRandom()
{
MapX = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / 608.0f));
MapY = MapX;
}
然后,我将精灵的当前位置传递给此函数
void AIntelligence::RandomMove(float PosX, float PosY)
{
this->PosX = PosX;
this->PosY = PosY;
if (PosX == MapX || PosY == MapY) //If the current is the same as the generated random, then
{ generate it again.
GenRandom();
}
else
{
if (PosX < MapX || PosY < MapY) //If not then I see if the position less than the
{ generated and translate it.
this->PosX += 8.0f;
this->PosY += 8.0f;
}
else if (PosX > MapX || PosY > MapY)
{
this->PosX -= 8.0f;
this->PosY -= 8.0f;
}
else
this->PosX += 0.0f;
this->PosY += 0.0f;
}
}
在我的消息循环中,这是我如何调用方法
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
Inputs->GetInput(); //Not related
Moving->RandomMove(PosX,PosY);
D3DXVECTOR2 SpritePos = D3DXVECTOR2(Moving->getPosX(), Moving->getPosY());
PosX = Moving->getPosX();
PosY = Moving->getPosY();
Graphic->ClearBegin(); //Begin the direct3d scene
Sprite->Begin(D3DXSPRITE_ALPHABLEND);
float Radian = D3DXToRadian(Rotation);
D3DXMatrixTransformation2D(&Mat, NULL, 0.0f, &SpriteScaling, &SpriteCenter, Radian, &SpritePos); // This is where the transformation is set.
Sprite->SetTransform(&Mat);
Sprite->Draw(Texture, NULL, NULL, NULL, D3DCOLOR_XRGB(255, 255, 255));
Sprite->End();
Graphic->EndPresent();
}
精灵确实移动但只向右移动。一旦它到达同一个地点,它只会停留在那里震动......对不起,如果我的解释不够清楚或者没有提供足够的信息。
答案 0 :(得分:1)
以下是一些可以帮助您的事情:
1)在RandomMove
中,您的上一个else
没有大括号,因为您正在执行两项操作,您应该像在其他地方一样将它们包裹在大括号中< / p>
2)float
比较很棘手。您的PosX == MapX || PosY == MapY
不太可能触发。更好的想法是计算当前位置和随机位置之间的distance
,然后在distance
小于epsilon
(小值)时执行代码。这是关于浮点比较(link)
3)GenRandom
始终为MapX
和MapY
分配相同的值。您应该尝试执行两个随机调用(并且可能使用const float
来定义您的最大值或使其可配置而不是硬编码该宽度
4)您的RandomMove
方法有点误导。它没有执行随机移动,而是转向MapX
和MapY
。您应该将来自移动代码的GenRandom
来电分开。
5)您的移动代码仅适用于对角线,因为您始终在同一方向上同时增加或减少两个轴的位置。
以下是您的代码可能如下所示的建议(未经过测试):
void AIntelligence::GenRandom(const float in_MaxValueX, const float in_MaxValueY)
{
MapX = in_MaxValueX * (float)rand() / (float)RAND_MAX;
MapY = in_MaxValueY * (float)rand() / (float)RAND_MAX;
}
bool AIntelligence::MoveTowards(const float in_PosX, const float in_PosY)
{
// how far are we from our objective
const float distX = in_PosX - PosX; // by calculating the distance from the target position, it makes our speed calculations easier later on
const float distY = in_PosY - PosY;
// tolerance in pixels
const float tolerance = 1.0f;
const float absDistX = abs(distX);
const float absDistY = abs(distY);
if(absDistX <= tolerance && absDistY <= tolerance) // destination reached
return true;
else
{
// here, normally, you would use a desired speed AND a delta time (your message loop is not really good for that though) to compute how much movement you can execute in a given frame
const float movement = min(10.f, absDistX + absDistY); // by using min, we're making sure not to overshoot our destination
// compute how this movement is spread on each axis
const float movementX = movement * distX / (absDistX + absDistY);
const float movementY = movement * distY / (absDistX + absDistY);
PosX += movementX;
PosY += movementY;
}
return false;
}
// in your loop
if(Moving->MoveTowards(MapX, MapY))
{
Moving->GenRandom(608.f, 608.f); // you should definitely not hardcode these values
}
如果您不太了解
部分,请随时发表评论