1

Ship Asteroid primitive:

img

just draw a Ship for Asteroid game but cant move and rotate ship correctly

  1. Problem: Cant find how use the Angle variable to rotate ship by center correctly;
  2. Problem: Cant find how use angle with position to got correct direction to move ship

Look my code and if possible help me:

typedef struct {float x; float y; float z; float angle;} point2D;

class player    //player class is ship
{
protected:

public:

    point2D position, angle;

    player()
    {
        position.x = 0.0; 
        position.y = 0.0;
        angle.z = 0.0;
    }

    void set_position(float x, float y) //Set position of player
    { 
        position.x=x;
        position.y=y;
    }
    void draw_ship()
        {

                glPushMatrix();
                glTranslatef(position.x,position.y,0);
                glRotatef(angle.z, 0.,0.,0.1);     
                glScalef(0.10,0.075,0.10);
                glBegin(GL_LINE_LOOP);
                                            glColor3ub(redc, greenc, bluec);                        
                    glVertex2f( 1.0f, 2.0f);                
                    glVertex2f( 1.4f, 0.4f);                
                    glVertex2f( 1.2f, 0.6f);    
                    glVertex2f( 0.8f, 0.6f);    
                    glVertex2f( 0.6f, 0.4f);
                glEnd();

                glPopMatrix();
    }


};
 player ship;

void display() {
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
   glClear(GL_COLOR_BUFFER_BIT);// Clear the color buffer (background

   glEnable( GL_TEXTURE_2D );

   background();
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
   glDisable( GL_TEXTURE_2D );

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity(); 

   ship.draw_ship();

   glutSwapBuffers();   // Double buffered - swap the front and back buffers
}

* Callback handler for special-key event */
void specialKeys(int key, int x, int y) {
    switch (key) {

       case GLUT_KEY_RIGHT:    
         ship.angle.z -= 10.0f;
       break; 

       case GLUT_KEY_LEFT:   
         ship.angle.z += 10.0f;
       break;            
       case GLUT_KEY_UP: 
         ship.position.x = ship.position.x + sin(ship.angle.z) * 0.02;
         ship.position.y = ship.position.y + cos(ship.angle.z) * 0.02;

         printf("posx is: %f",  ship.position.x);
         printf("posy is: %f", ship.position.y);

      break;       

   }

}

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • 2
    Is `ship.angle.z` in degrees or in radians? You're using it both ways (`glRotatef()` takes degrees, `sin()`/`cos()` take radians). – genpfault Sep 26 '19 at 14:33
  • if you know the formula to rotate the ship by center and move to correct direction please post here.I started angle.z = 0.0f i think started in radians.The rotate by key no ocurr in center orign. of ship and movement in glTranslatef() working with many distortions not good – yourbdeal dresdenptc Sep 26 '19 at 15:48
  • i just convert rad to degree and ship direction working ship.angle.z -= 0.1f; ship.angled.z = -ship.angle.z * 180.0 / 3.1415926535897932384626433832795028841 ; But cant made rotation by center origin the ship yet – yourbdeal dresdenptc Sep 26 '19 at 16:47
  • see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) at the end there are links to examples for camera and player control in 3D ... in 2D is the same ... so either use cumulative matrices or rotate aroun dnon zero center ... (you must translate so center of rotation become `(0,0,0)` then rotate and then translate back to original position ... – Spektre Sep 27 '19 at 06:42
  • i need konw if possible create new point vertex to my ship then rotate the ship by this point just that – yourbdeal dresdenptc Sep 27 '19 at 12:11

1 Answers1

0

You problem is that glRotate is always rotating around (0,0,0) ... so to make your transform right first rotate identity and then translate. But there is a slight problem because glTranslate will use local coordinates and you need global ... luckily you can set the matrix origin directly. As the comments where not enough for you here how it would look like:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();                   // unit matrix
glRotatef(angle.z,0.0,0.0,1.0);     // rotate around (0,0,0) and z axis
double m[16];
glGetDoublev(GL_MODELVIEW_MATRIX,m);// get actual matrix into CPU side memory/code
m[12]=position.x;                   // change the global position
m[13]=position.y;
m[14]=0.0;
glLoadMatrix(m);                    // update GL matrix with the changed one
glScalef(0.10,0.075,0.10);          // scale ship

In case your position is in already scaled coordiantes then the scale will go directly after the rotate.

Beware I wrote this directly in answer editor so there might be minor syntax errors ...

btw you can use the m also for movement in ship direction m[0,1,2] is x axis direction and m[4,5,6] is y axis. not sure in which your ship model points. You just add this forward vector multiplied by speed/deltatime to your position in some timer.

For more info about matrices see: Understanding 4x4 homogenous transform matrices

Spektre
  • 49,595
  • 11
  • 110
  • 380