我有一个项目,我想制作一个使用小行星式船只的游戏,以展示AI寻路和转向行为。
对象存储三角形的质心(否则是玩家的位置)和船只的位置的值。以度为单位的方向,然后像这样计算三个顶点的位置:
A是三角形的鼻子。当方向为0度时,船的鼻子位于X轴上,偏移SIZE,这决定了船的大小等于其边界圆的半径。
顶点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());
}
答案 0 :(得分:0)
我在您的代码中发现了一些问题,这些问题可能会影响到您所看到的结果。
首先,您将坐标作为整数处理。因此,小数位被切断,值越来越小。使用float或甚至双倍。
第二件事是旋转分两步进行。第一步(计算x坐标)是正确的。但是,第二步(计算y坐标)是错误的。您使用新的x坐标,但应提供旧的x坐标。无论如何,您应该实现一个旋转整个向量而不是它们的一部分的方法。为什么不使用DirectX数学函数?