2

マップ上を (ウィンドウ サイズ間で) スムーズに移動できる AI を作成する方法について、いくつかの洞察を得たいと思います。たとえば、AI が定義された場所に到達すると、別の場所に移動します。これが私が試したことです、

まず、ウィンドウ サイズが 640,640 であるため、0.0f から 608.0f までのランダムな浮動小数点数を取得します。

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();
        }

スプライトは動きましたが、右下にしか移動しませんでした。そして、同じ特定の場所に到達すると、そこにとどまり、振動するだけです....私の説明が十分に明確でなかったり、必要な情報を十分に提供していなかったりした場合は申し訳ありません。 ここに画像の説明を入力

4

1 に答える 1

1

ここにあなたを助けるべきいくつかのことがあります:

1) ではRandomMove、最後elseに中かっこがありません。2 つの操作を実行しているため、他の場所で行ったように、両方を中かっこで囲む必要があります。

2)float比較が難しい。あなたのPosX == MapX || PosY == MapY意志がトリガーされる可能性は非常に低いです。より良いアイデアはdistance、現在の位置とランダムな位置の間のを計算し、 (小さい値)distanceより小さい場合にコードを実行することです。epsilonこれは、フロートの比較に関するかなり詳細な投稿です(リンク

3)GenRandomと に常に同じ値を割り当てMapXますMapY。代わりに 2 つのランダムな呼び出しを実行するようにしてください (おそらく aconst 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
}

よくわからない部分があれば遠慮なくコメントしてください

于 2014-12-07T07:07:35.313 に答える