0

AI の経路探索と操舵動作を示すために、小惑星スタイルの船を使用するゲームを作成したいプロジェクトがあります。

このオブジェクトは、三角形の重心 (それ以外の場合はプレイヤーの位置) と船の向き (度単位) の値を保存し、次のように 3 つの頂点の位置を計算します。

Aは三角形の鼻です。向きが 0 度の場合、船の機首は SIZE だけオフセットされた X 軸上に置かれます。これにより、船のサイズが決定され、境界円の半径に等しくなります。

頂点 B と C は A の位置からそれぞれ 120 度と 240 度回転し、プログラムは各頂点間に線分を描画します。

プログラムを開始すると、これは見事に機能し、バウンディング サークル、方向ベクトル、船は期待どおりに見えます。

ただし、左右の矢印キーで角度が増減するようなコントロールを実装しました。このコントロールはテスト済みで、希望どおりに機能することが証明されています。これが発生すると、方向ベクトルがそれに応じて調整され、船が回転します... しかし、ほんの一部です. どの方向に回転しても、ポイントはすぐに質量の中心に移動し、中心で崩壊して永遠に消えます。

//Convert degrees into radians
float Ship::convert(float degrees){
    return degrees*(PI/180);
}

//Rotation X-Coord
int Ship::rotateX(int x, int y, float degrees){
    return (x*cos(convert(degrees)))-(y*sin(convert(degrees)));
}

//Rotate Y-Coord
int Ship::rotateY(int x, int y, float degrees){
    return x*sin(convert(degrees))+y*cos(convert(degrees));
}

//Rotate the Ship
void Ship::rotateShip(float degrees){
    vertA [0]=rotateX(vertA [0], vertA [1], degrees);
    vertA [1]=rotateY(vertA [0], vertA [1], degrees);
    vertB [0]=rotateX(vertB [0], vertB [1], degrees);
    vertB [1]=rotateY(vertB [0], vertB [1], degrees);
    vertC [0]=rotateX(vertC [0], vertC [1], degrees);
    vertC [1]=rotateY(vertC [0], vertC [1], degrees);
}

回転機能は正常に機能しますが、船の回転が機能しているかどうかはわかりません。vert 変数は、その頂点の X 座標と Y 座標を格納する配列です。各頂点を船の向きの角度だけ回転させると、理論的には三角形がその中心で回転するはずですよね?

頂点はすべて原点に対して調整され、Game オブジェクトの drawShip() 関数はこれらの座標を取得し、playerX と playerY を追加して、完全に描画された船をプレイヤーの位置に移動します。基本的には、原点に移動し、回転させ、プレーヤーの位置に戻します。

それが役立つ場合は、ゲーム オブジェクトから関連する関数を含めます。このコードでは、psp が Ship オブジェクトです。Draw ship は、ship オブジェクトのすべてのパラメータを受け取り、動作するはずですが、望ましくない結果が得られます。

//Draw Ship
void Game::drawShip1(int shipX, int shipY, int vel, int alpha, int size, int* vertA, int* vertB, int* vertC, int r, int g, int b){
    //Draw a bounding circle
    drawCircle(shipX, shipY, size, 0, 255, 255);
    //Draw the ship by connecting vertices A, B, and C
    //Segment AB
    drawLine(shipX+vertA[0], shipY+vertA[1], shipX+vertB [0], shipY+vertB [1], r, g, b);
    //Segment AC
    drawLine(shipX+vertA[0], shipY+vertA[1], shipX+vertC [0], shipY+vertC [1], r, g, b);
    //Segment BC
    drawLine(shipX+vertB[0], shipY+vertB[1], shipX+vertC [0], shipY+vertC [1], r, g, b);

}


void Game::ComposeFrame()
{
    float pAlpha=psp.getAlpha();
    if(kbd.LeftIsPressed()){
        pAlpha-=1;
        psp.setAlpha(pAlpha);
        psp.rotateShip(psp.getAlpha());
    }
    if(kbd.RightIsPressed()){
        pAlpha+=1;
        psp.setAlpha(pAlpha);
        psp.rotateShip(psp.getAlpha());
    }
    //Draw Playership
    drawShip1(psp.getX(), psp.getY(), psp.getV(), psp.getAlpha(), psp.getSize(), psp.getVertA(), psp.getVertB(), psp.getVertC(), psp.getR(), psp.getG(), psp.getB());
    drawLine(psp.getX(), psp.getY(), psp.getX()+psp.rotateX(0+psp.getSize(), 0, psp.getAlpha()), psp.getY()+psp.rotateY(0+psp.getSize(), 0, psp.getAlpha()), psp.getR(), psp.getG(), psp.getB());
}
4

1 に答える 1

0

あなたのコードには、表示されている結果につながる可能性のあるいくつかの問題があります。

まず、座標を整数として扱います。これにより小数点以下が切り捨てられ、値がどんどん小さくなっていきます。float または double を使用します。

2 つ目は、回転が 2 段階で適用されることです。最初のステップ (x 座標の計算) は正しいです。ただし、2 番目のステップ (y 座標の計算) は誤りです。新しい x 座標を使用しますが、古いものを提供する必要があります。とにかく、ベクトルの一部ではなく完全なベクトルを回転させるメソッドを実装する必要があります。DirectX の数学関数を使用しないのはなぜですか?

于 2013-04-03T15:42:00.057 に答える