0

我有一个项目,我想制作一个使用小行星式飞船的游戏,以展示 AI 寻路和转向行为。

该对象存储三角形质心位置的值(否则玩家的位置)和船只的方向(以度为单位),然后计算三个顶点的位置,如下所示:

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

旋转功能工作正常,但我不能确定旋转 Ship 是否正常工作。看起来它应该 - vert 变量是存储该顶点的 X 和 Y 坐标的数组。如果我按船的方位角旋转每个顶点,理论上它应该在其中心旋转三角形,对吗?

verts 都是关于原点校准的,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

我在您的代码中看到了几个问题,这些问题可能会增加您所看到的结果。

第一件事是将坐标作为整数处理。因此,小数位被截断,值越来越小。使用浮点数甚至双倍。

第二件事是分两步应用旋转。第一步(计算x坐标)是正确的。但是,第二步(计算 y 坐标)是错误的。您使用新的 x 坐标,但应提供旧的 x 坐标。无论如何,您应该实现一个旋转完整向量而不是其中一部分的方法。为什么不使用 DirectX 数学函数?

于 2013-04-03T15:42:00.057 回答