2014-12-06 85 views
2

我想知道如何制作AI,它可以在地图上平滑地走动(在窗口大小之间)。就像,如果AI达到了定义的地点,那么它会走到另一个地方。 这是我试过的,创建一个简单的2D AI C++

首先,我得到一个从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(); 
     } 

的精灵做移动但只能向右移动。一旦它达到相同的地点,它只会停留在那里,并震动......很抱歉,如果我的解释不够清楚或没有提供足够的信息需要。 enter image description here

回答

1

这里有几件事情,应该可以帮助您:

1)在RandomMove,你最后else没有括号,因为你正在执行两项操作,你应该在括号括住他们两个像你在别处做的那样

2)float比较棘手。这是不太可能的,你的PosX == MapX || PosY == MapY会触发。如果distance小于epsilon(小值),则更好的办法是计算当前位置和随机位置之间的distance,然后执行代码。这里是一个非常详细的关于浮点数比较的文章(link

3)GenRandom总是将相同的值分配给MapXMapY。你应该尝试,而不是执行两个随机电话(可能使用一个const float来定义您的最大值或使其配置,而不是硬编码该宽度

4)你RandomMove方法是有点误导。它不会执行随机移动,它将朝着MapXMapY。您应该将移动代码中的呼叫分开到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 
} 

随意评论,如果有部分你不太明白

+0

嘿@emartel感谢这么很多有用的指南。由于我正在计算距离,是否可以使用'D3DXVECTOR2(x,y)'?我的意思是,我如何使用这些向量来翻译精灵? – Student 2014-12-07 08:36:50

+0

@Student我会远离API矢量类,并使用我自己的。当你打电话给MoveToward时,你的翻译会发生,所以你应该没问题 – emartel 2014-12-07 19:45:55

+0

好的。谢谢:D它已经正常工作了。 – Student 2014-12-07 20:47:26