home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / METEOR.PAK / SPRITE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  5.4 KB  |  256 lines

  1. //--------------------------------------------------------------------------
  2. // Turbo Meteor -- Copyright (c) 1995, Borland International
  3. //--------------------------------------------------------------------------
  4. #include <owl/pch.h>
  5. #include "sprite.h"
  6.  
  7. // adjust - value to convert degrees to radians
  8. //
  9. //  pi can be computed as atan(1)*4,
  10. //
  11. //  and there are 2*pi radians in 360 degrees so:
  12. //
  13. //  adjust = 2*pi/360 = pi/180 = atan(1)*4/180 = atan(1)/45
  14. //
  15. const double adjust = atan(1)/45;
  16.  
  17. double sinTable[360];
  18. double cosTable[360];
  19.  
  20. double sind( int angle )
  21. {
  22.   return sinTable[(angle+360)%360];
  23. }
  24.  
  25. double cosd( int angle )
  26. {
  27.   return cosTable[(angle+360)%360];
  28. }
  29.  
  30. void InitSinCosTables()
  31. {
  32.   int i;
  33.   for (i=0;i<360;i++) {
  34.     sinTable[i] = sin(adjust*i);
  35.     cosTable[i] = cos(adjust*i);
  36.   }
  37. }
  38.  
  39. #pragma startup InitSinCosTables
  40.  
  41. Sprite::~Sprite()
  42. {
  43. }
  44.  
  45. SpriteList::~SpriteList()
  46. {
  47.   Sprite* chase = root;
  48.   while (chase) {
  49.     Sprite* next = chase->next;
  50.     delete chase;
  51.     chase = next;
  52.   }
  53. }
  54.  
  55. void SpriteList::Add( Sprite* sprite )
  56. {
  57.   count++;
  58.   sprite->next = root;
  59.   sprite->owner = this;
  60.   root = sprite;
  61. }
  62.  
  63. void SpriteList::DrawAll( TMemoryDC& dc )
  64. {
  65.   Sprite *temp = root;
  66.   while (temp!=0) {
  67.     if (!(temp->condemned))
  68.       temp->Draw( dc );
  69.     temp=temp->next;
  70.   }
  71. }
  72.  
  73. int SpriteList::UpdateAll()
  74. {
  75.   int    points = 0;
  76.   Sprite *previous = 0;
  77.   Sprite *current = root;
  78.  
  79.   while (current != 0) {
  80.     // if the object is not condemned, call it's update function
  81.     //
  82.     if (!(current->condemned)) {
  83.       Sprite* next = current->next;
  84.       previous = current;
  85.       current = next;
  86.       points += previous->Update();
  87.     }
  88.     // if the object is condemned, delete it from the list
  89.     //
  90.     else {
  91.       // special case if we're deleting the root node
  92.       //
  93.       if (previous==0) {
  94.         root = current->next;
  95.         delete current;
  96.         count--;
  97.         current = root;
  98.       }
  99.       else {
  100.         previous->next = current->next;
  101.         Sprite* temp = current->next;
  102.         delete current;
  103.         current = temp;
  104.         count--;
  105.       }
  106.     }
  107.   }
  108.   return points;
  109. }
  110.  
  111. Sprite* SpriteList::CheckForHitMeteor( TPoint& p )
  112. {
  113.   Sprite *temp = root;
  114.   while (temp!=0) {
  115.     if ((strncmp(temp->DebugInfo(),"Meteor",6)==0) &&  // *BBK* cheezy
  116.         (temp->boundingRect.Contains( p )))
  117.         return temp;
  118.     temp=temp->next;
  119.   }
  120.   return 0;
  121. }
  122.  
  123. Meteor::Meteor( const TPoint& aOrigin, const TSize& aMomentum, int aSize, 
  124.                 int aSpawnCount )
  125. :
  126.   Sprite( TSize( 600,400 ) )
  127. {
  128.   origin = aOrigin;
  129.   mx = aMomentum.cx;
  130.   my = aMomentum.cy;
  131.   size = aSize;
  132.   spawnCount = aSpawnCount;
  133.   for (int i=0;i<10;i++) {
  134.     angle[i] = (angle1[i]+random(20)-10)%360;
  135.     radius[i] = (radius1[i]+random(10)-5)/(4-size);
  136.   }
  137.   angularMomentum = random(7)-4;
  138.   currentAngle = 0;
  139.   count = count1;
  140. }
  141.  
  142. void Meteor::Hit()
  143. {
  144.   if (size > 1) {
  145.     int newSize = size - 1;
  146.     for (int i=0; i<spawnCount; i++)
  147.       owner->Add( new Meteor( origin, TSize( random(10)-4, random(10)-4 ),
  148.                               newSize, newSize ) );
  149.   }
  150.   condemned=true;
  151. }
  152.  
  153. void Meteor::Draw( TMemoryDC& dc )
  154. {
  155.   TPoint temp;
  156.   TPoint points[10];
  157.   int i;
  158.  
  159.   temp =TPoint( radius[0]*sind(angle[0]+currentAngle),
  160.                 radius[0]*cosd(angle[0]+currentAngle) );
  161.   ResetBoundingRect();
  162.   ExpandBoundingRect( temp+origin );
  163.   points[0]=temp+origin;
  164.   for (i=1;i<=count;i++) {
  165.     temp = TPoint( radius[i%count]*sind(angle[i%count]+currentAngle),
  166.                    radius[i%count]*cosd(angle[i%count]+currentAngle) );
  167.     ExpandBoundingRect( temp+origin );
  168.     points[i] = temp+origin;
  169.   }
  170.   points[count]=points[0];
  171.   dc.Polyline( points, count+1 );
  172. }
  173.  
  174. int Shot::Update()
  175. {
  176.   // shots die after a fixed amount of time
  177.   //
  178.   if (timeToDie>0) {
  179.     origin+=TPoint(mx,my);
  180.     timeToDie--;
  181.     if (timeToDie==0)
  182.       condemned = true;
  183.   }
  184.  
  185.   Wrap();  // if the shot is off the screen, wrap to other side
  186.  
  187.   // check against all meteors in the list, to see if any are
  188.   // colliding with ourself
  189.  
  190.   Sprite* meteor = owner->CheckForHitMeteor( origin );
  191.  
  192.   // if so, tell the meteor it was hit, and mark ourself for
  193.   // deletion
  194.  
  195.   Meteor* m = TYPESAFE_DOWNCAST(meteor, Meteor);
  196.   if (m) {
  197.     int size = m->GetSize();
  198.     condemned = true;
  199.     m->Hit();
  200.     switch (size) {
  201.       case 1:
  202.         return 500;
  203.       case 2:
  204.         return 50;
  205.       case 3:
  206.         return 5;
  207.     }
  208.   }
  209.   return 0;
  210. }
  211.  
  212. const char *Meteor::DebugInfo()
  213. {
  214.   static char temp[100];
  215.   wsprintf(temp,"Meteor(%d)",size);
  216.   return temp;
  217. }
  218.  
  219. const char *Message::DebugInfo()
  220. {
  221.   static char temp[100];
  222.   wsprintf(temp,"Message '%s'",text);
  223.   return temp;
  224. }
  225.  
  226. Message::Message( const TPoint& aOrigin, int aBufferLen )
  227. :
  228.   Sprite( TSize(600,400) )
  229. {
  230.   text = new char[ aBufferLen+1 ];
  231.   bufferLen = aBufferLen;
  232.   origin = aOrigin;
  233. }
  234.  
  235. void Message::Draw( TMemoryDC& dc )
  236. {
  237.   TPoint temp = origin;
  238.   dc.SaveDC();
  239.   dc.SetTextColor(TColor(255, 255, 255));
  240.   dc.TextOut(temp, text);
  241.   dc.RestoreDC();
  242. }
  243.  
  244. Message::~Message()
  245. {
  246.   delete [] text;
  247. }
  248.  
  249. // values used to initialize meteors.  these values are randomly
  250. // tweaked, so each meteor looks different
  251. //
  252. int  angle1[10] = { 0,45,90,135,180,225,270,315,0,0 };
  253. int  radius1[10] = { 30,30,30,30,30,30,30,30,0,0 };
  254. int  count1 = 8;
  255.  
  256.