I have a project in which I want to make a game that uses Asteroids-style ships in order to demonstrate AI pathfinding and steering behaviors.
The object stores values for the position the centroid of the triangle (Otherwise the player's position) and the ships' orientation in degrees, then calculates the position of the three vertices like so:
A is the nose of the triangle. When the the orientation is 0 degrees, the ship's nose sits on the X-axis offset by SIZE, which detemines the size of the ship which is equal to the radius of its bounding circle.
Vertices B and C are rotated from the position of A 120 and 240 degrees respecively, then the program draws line segments between each vertex.
When I start the program, this works beautifully, and my bounding circle, orientation vector, and ship look how I expect them to.
However, I implemented a control such that angle is incremented and decremented with the left and right arrow keys. This control has been tested and proven to work as desired. When this happens, the orientation vector adjusts accordingly, and the ship rotates... but only sort of. The points immediately move in to the center of the mass until they collapse on the center and disappear forever, regardless of which direction I rotate in.
//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);
}
The rotate functions work fine, but I can't be sure that rotating the Ship is working. It seems that it should- the vert variables are arrays that store the X and Y coord of that vertex. If I rotate each vertex by the orientation angle of the ship, it should in theory spin the triangle on its center, right?
The verts are all calibrated about the origin, and the drawShip() function in the Game object takes those coords and adds the playerX and playerY to translate the fully drawn ship to the position of the player. So essentially, translating it to the origin, rotating it, and translating it back to the position of the player.
If it helps, I will include the relevant functions from the Game Object. In this code, psp is the Ship object. Draw ship takes all the parameters of the ship object and should work, but I'm getting unwanted results.
//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());
}
rotateX
androtateY
. They assume rotation around(0,0)
. Add a "center point" to their parameters instead. – Drew Dormann