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