www.pudn.com > airhockey.rar > puck.cpp


#include "puck.h" 
 
// Load() 
// desc: not used by CPuck 
void CPuck::Load() 
{ 
     // override virtual function 
} 
 
// Unload() 
// desc: not used by CPuck 
void CPuck::Unload() 
{ 
     // override virtual function 
} 
 
// Draw() 
// desc: renders the puck as a solid cylinder 
void CPuck::Draw() 
{ 
     glPushMatrix(); 
          glTranslatef(position.x, position.y, position.z); 
          glScalef(radius, radius, radius); 
          glColor3f(0.0, 0.0, 0.0);             // black 
 
          // draw side ring of puck 
          glBegin(GL_TRIANGLE_STRIP); 
          for (int i = 0; i < 16; i++) 
          {               
               glVertex3fv(&puckData[i+16][0]); // top  
               glVertex3fv(&puckData[i][0]);    // bottom 
          } 
          glVertex3fv(&puckData[16][0]); 
          glVertex3fv(&puckData[0][0]); 
          glEnd(); 
 
          // draw top and bottom of puck 
          glBegin(GL_TRIANGLE_FAN); 
               glVertex3f(0.0, puckData[0][1], 0.0); 
               for (i = 0; i < 16; i++) 
                    glVertex3fv(&puckData[i][0]); 
               glVertex3fv(&puckData[0][0]); 
          glEnd(); 
          glBegin(GL_TRIANGLE_FAN); 
               glVertex3f(0.0, puckData[31][1], 0.0); 
               for (i = 16; i < 32; i++) 
                    glVertex3fv(&puckData[i][0]); 
               glVertex3fv(&puckData[16][0]); 
          glEnd(); 
 
     glPopMatrix(); 
} 
 
// Animate() 
// desc: overridable version not used by CPuck 
void CPuck::Animate(scalar_t deltaTime) 
{ 
     // just used to override virtual function 
} 
 
// Animate() 
// desc: handles physics and collision detection 
//       within table space defined by table 
void CPuck::Animate(scalar_t deltaTime, CTable *table) 
{ 
     if (deltaTime <= 0) return; 
 
     double fastestTime = deltaTime; 
     CPlane *planeCollision = NULL; 
     for (int idx = 0; idx < 4; idx++) 
     { 
          CPlane *plane = &table->tableWalls[idx]; 
          double collisionTime; 
          double a, b, c; 
 
          // dot product 
          a = plane->N % (acceleration * 0.5); 
          b = plane->N % velocity; 
          c = plane->N % position + plane->D - radius; 
 
          if (a == 0)         // first degree 
          { 
               if (b != 0 && c != 0)    // must have velocity 
               { 
                    collisionTime = -c/b; 
                    if (collisionTime >= 0 && collisionTime < fastestTime) 
                    { 
                         fastestTime = collisionTime; 
                         planeCollision = plane; 
                    } 
               } 
          } 
          else 
          {    //   Second degree equation 
               double D = b*b - 4*a*c;       //   Calc determinant 
               if (D >= 0) 
               {     
                    //   Calc solution (cannot be negative, so the negative solution is dropped) 
                    collisionTime = (- b - sqrt(D)) / (2*a); 
                    if (collisionTime >= 0 && collisionTime < fastestTime) 
                    { 
                         fastestTime = collisionTime; 
                         planeCollision = plane;   
                    } 
               } 
          } 
     } 
 
     // apply friction (coefficient = 0.2) 
     if (velocity.Length() > 0.0) 
          acceleration = -velocity * 0.2; 
 
     //   Move to collision point & set velocity there 
     position += velocity * fastestTime + acceleration * (fastestTime*fastestTime*0.5); 
     velocity += acceleration * fastestTime; 
 
     // only allow velocity to max out at 800 
     if (velocity.Length() > 800.0) 
          velocity |= 800.0;       // set velocity equal to 800 
           
     if (planeCollision) 
     {    //   Bounce - invert height direction 
          velocity = velocity.Reflection(planeCollision->N); 
     } 
 
     //   Recursive call 
     Animate(deltaTime - fastestTime, table); 
}