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

  1. //--------------------------------------------------------------------------
  2. // Turbo Meteor -- Copyright (c) 1995, Borland International
  3. //--------------------------------------------------------------------------
  4. #ifndef SPRITE_H
  5. #define SPRITE_H
  6.  
  7. #include <owl/listbox.h>
  8. #include <math.h>
  9.  
  10. const MAX_SPEED = 20;
  11.  
  12. double sind( int angle );
  13. double cosd( int angle );
  14.  
  15. class SpriteList;  // forward declaration for use in Sprite class
  16.  
  17. // class Sprite -- a base class for any object which will be displayed
  18. // on the screen.
  19. //
  20. class Sprite {
  21.   friend class SpriteList;   // so the SpriteList class can access
  22.                              // data members
  23.   public:
  24.     Sprite( const TSize& aScreenSize ) {
  25.       screenSize = aScreenSize;
  26.       ResetBoundingRect();
  27.       mx=my=0;
  28.       condemned = false;
  29.       next = 0;
  30.       owner = 0;
  31.     }
  32.  
  33.     virtual ~Sprite();
  34.  
  35.     void SetMomentum( TSize& newMomentum ) {
  36.       mx = newMomentum.cx;
  37.       my = newMomentum.cy;
  38.     }
  39.  
  40.     void Condemn() { condemned = true; }
  41.  
  42.     // Update -- by default, moves sprite based on it's momentum.  Should
  43.     // return a value which will be added to the score
  44.     //
  45.     virtual int Update() {
  46.       origin.x+=mx;
  47.       origin.y+=my;
  48.       Wrap();
  49.       return 0;
  50.     }
  51.  
  52.     void ResetBoundingRect() { boundingRect = TRect( origin, origin ); }
  53.  
  54.     // ExpandBoundingRect -- given a point, expand our bounding rectangle
  55.     // to include this point.
  56.     //
  57.     void ExpandBoundingRect( TPoint& p ) {
  58.       if (p.x<boundingRect.left)
  59.         boundingRect.left = p.x;
  60.       if (p.y<boundingRect.top)
  61.         boundingRect.top = p.y;
  62.       if (p.x>boundingRect.right)
  63.         boundingRect.right = p.x;
  64.       if (p.y>boundingRect.bottom)
  65.         boundingRect.bottom = p.y;
  66.       boundingRect.Normalize();
  67.     }
  68.  
  69.     // Default draw function draws a pixel at the sprites origin
  70.     //
  71.     virtual void Draw( TMemoryDC& dc ) {
  72.       dc.SetPixel( origin, TColor( 255, 255, 255 ) );
  73.     }
  74.  
  75.     // DebugInfo -- returns string to display in the debugging log window
  76.     //
  77.     virtual const char *DebugInfo() { return "Sprite"; }
  78.  
  79.     // Wrap -- adjust the sprites origin, if it strays off the edge of
  80.     // the window
  81.     //
  82.     void Wrap() {
  83.       origin.x = (origin.x + screenSize.cx) % screenSize.cx;
  84.       origin.y = (origin.y + screenSize.cy) % screenSize.cy;
  85.     }
  86.  
  87.   protected:
  88.     SpriteList *owner;         // pointer to the list which contains us
  89.     Sprite     *next;          // pointer to next sprite in the list
  90.     TPoint     origin;         // sprites position in the window
  91.     TRect      boundingRect;   // a rectangle which completely encloses sprite
  92.     double     mx,my;          // current direction of sprite
  93.     TSize      screenSize;     // size of screen which contains the sprite
  94.                                // used to wrap objects from one side of screen to other
  95.     bool       condemned;      // used to mark dead objects
  96.  
  97.   private:
  98.     Sprite() {}                // to generate compile-time error
  99.  
  100. };
  101.  
  102. // SpriteList -- contains a list of sprites.  Contains specific
  103. // functions for collision detection
  104. //
  105. class SpriteList {
  106.   public:
  107.     SpriteList() {
  108.       root = 0;
  109.       count = 0;
  110.     }
  111.    ~SpriteList();
  112.  
  113.     void    Add( Sprite* sprite );
  114.     void    DrawAll( TMemoryDC& dc );
  115.     void    UpdateLog( TListBox *lb );
  116.     int     UpdateAll();
  117.     Sprite* CheckForHitMeteor( TPoint& p );
  118.  
  119.     int count;
  120.  
  121.   private:
  122.     Sprite *root;
  123. };
  124.  
  125. // the following are defined in sprite.cpp
  126.  
  127. extern int angle1[10];
  128. extern int radius1[10];
  129. extern int count1;
  130.  
  131. // Meteor -- a rock, floating in space.  The meteor is specified as
  132. // a series of polor-coordinate points (an angle and a radius).  This
  133. // allows for faster calculation when making the meteors rotate as
  134. // they float about.
  135. //
  136. class Meteor : public Sprite {
  137.   public:
  138.     Meteor( const TPoint& aOrigin, const TSize& aMomentum, 
  139.             int aSize, int aSpawnCount );
  140.  
  141.     int GetSize() { return size; }
  142.     void SetRotationAngle( int angle );
  143.     int Update() {
  144.       origin.x+=mx;
  145.       origin.y+=my;
  146.       Wrap();
  147.       currentAngle = (currentAngle+angularMomentum+360)%360;
  148.       return 0;
  149.     };
  150.     void Hit();
  151.     virtual void Draw( TMemoryDC& dc );
  152.     virtual const char *DebugInfo();
  153.  
  154.   private:
  155.     int    angularMomentum,    // how fast the meteor is spinning
  156.            currentAngle;       // current angle of rotation
  157.     int    angle[10],          // angle and radius of the points
  158.            radius[10];         //   which define the meteor
  159.     int    count;              // # of points which define the meteor
  160.     int    size;               // 1=tiny, 2=medium, 3=large rock
  161.     int    spawnCount;         // how many smaller meteors to create when hit
  162. };
  163.  
  164. // Shot -- a bullet (5 pixels in a cross pattern)
  165. //
  166. class Shot : public Sprite {
  167.   public:
  168.     Shot( const TPoint& aOrigin, const TSize& aMomentum, int aTimeToDie ):
  169.       Sprite( TSize(600,400) ) {  //*BBK*
  170.       origin = aOrigin;
  171.       mx = aMomentum.cx;
  172.       my = aMomentum.cy;
  173.       timeToDie = aTimeToDie;
  174.     }
  175.  
  176.     virtual void Draw( TMemoryDC& dc ) {
  177.       if (timeToDie>0) {
  178.         dc.SetPixel( origin, TColor(255,255,255) );
  179.         dc.SetPixel( origin+TPoint(1,0), TColor(255,255,255) );
  180.         dc.SetPixel( origin+TPoint(0,1), TColor(255,255,255) );
  181.         dc.SetPixel( origin+TPoint(0,-1), TColor(255,255,255) );
  182.         dc.SetPixel( origin+TPoint(-1,0), TColor(255,255,255) );
  183.       }
  184.     }
  185.  
  186.     virtual int Update();
  187.     virtual const char *DebugInfo() { return "Shot"; }
  188.  
  189.   private:
  190.     int timeToDie;            // shots dissapear after a set amount of time
  191. };
  192.  
  193. // Debris -- a spinning line.  it floats about for a few seconds and
  194. // disappears.  the player ship is turned into these when it is destroyed.
  195. //
  196. class Debris : public Sprite {
  197.   public:
  198.     Debris( const TPoint& aP1, const TPoint& aP2, const TSize& screenSize )
  199.     :
  200.       Sprite(screenSize)
  201.     {
  202.       p1 = aP1;
  203.       p2 = aP2;
  204.       mx = random(10)-5;
  205.       my = random(10)-5;
  206.       angularMomentum = random(10)-5;
  207.       timeToDie = 20 + random(5);
  208.     }
  209.  
  210.     int Update() {
  211.       if (timeToDie>0) {
  212.         p1+=TPoint(mx,my);
  213.         p2+=TPoint(mx,my);
  214.         timeToDie--;
  215.       } else
  216.         Condemn();
  217.       return 0;
  218.     }
  219.  
  220.     void Draw( TMemoryDC& dc ) {
  221.       dc.MoveTo(p1);
  222.       dc.LineTo(p2);
  223.     }
  224.  
  225.   private:
  226.     TPoint p1,p2;
  227.     int size;              // length of line
  228.     int angle;             // current angle of spinning line
  229.     int angularMomentum;   // rate of spin
  230.     int timeToDie;
  231. };
  232.  
  233. // Ship -- the player ship
  234. //
  235. class Ship : public Sprite {
  236.   public:
  237.     Ship( const TPoint& pos )
  238.     :
  239.       Sprite( TSize(600,400) )
  240.     {
  241.       origin = pos;
  242.       angle = 0;
  243.       radius=10;
  244.       thrust=0;
  245.       mx=my=0;
  246.     }
  247.  
  248.     virtual void Draw( TMemoryDC& dc ) {
  249.       TPoint p1,p2,p3,p4;
  250.  
  251.       p1 = TPoint( radius*sind(angle), radius*cosd(angle) );
  252.       p2 = TPoint( radius*sind(angle+130), radius*cosd(angle+130) );
  253.       p3 = TPoint( (radius/4)*sind(angle+180), (radius/4)*cosd(angle+180) );
  254.       p4 = TPoint( radius*sind(angle+230), radius*cosd(angle+230) );
  255.       dc.MoveTo( p1+origin );
  256.       dc.LineTo( p2+origin );
  257.       dc.LineTo( p3+origin );
  258.       dc.LineTo( p4+origin );
  259.       dc.LineTo( p1+origin );
  260.     }
  261.  
  262.     void Explode() {
  263.       Condemn();
  264.       TPoint p1,p2,p3,p4;
  265.       p1 = origin + TPoint( radius*sind(angle), radius*cosd(angle) );
  266.       p2 = origin + TPoint( radius*sind(angle+130), radius*cosd(angle+130) );
  267.       p3 = origin + TPoint( (radius/4)*sind(angle+180), (radius/4)*cosd(angle+180) );
  268.       p4 = origin + TPoint( radius*sind(angle+230), radius*cosd(angle+230) );
  269.  
  270.       owner->Add( new Debris( p1, p2, screenSize ) );
  271.       owner->Add( new Debris( p2, p3, screenSize ) );
  272.       owner->Add( new Debris( p3, p4, screenSize ) );
  273.       owner->Add( new Debris( p4, p1, screenSize ) );
  274.     }
  275.  
  276.     void Rotate( int adjust ) { angle = (angle+adjust+360)%360; }
  277.     void AddThrust( int adjust ) {
  278.       thrust+=adjust;
  279.       if (thrust<0) thrust=0;
  280.     }
  281.     int Update() {
  282.       int len;
  283.       mx+= thrust*sind( angle );
  284.       my+= thrust*cosd( angle );
  285.       len = (sqrt(mx*mx+my*my));
  286.       if (len>MAX_SPEED) {
  287.         mx = mx/len*MAX_SPEED;
  288.         my = my/len*MAX_SPEED;
  289.         thrust=0;
  290.       }
  291.       origin.x+=mx;
  292.       origin.y+=my;
  293.       Wrap();
  294.  
  295.       // check to see if we hit a meteor
  296.  
  297.       Sprite* meteor = owner->CheckForHitMeteor( origin );
  298.  
  299.       if (meteor)
  300.         return -9999;
  301.  
  302.       return 0;
  303.     }
  304.  
  305.     Shot* CreateNewShot() {
  306.       TSize shotDir( 10*sind(angle),10*cosd(angle) );
  307.       TPoint shotOrigin = TPoint( radius*sind( angle ), radius*cosd( angle ) );
  308.       return new Shot( origin+shotOrigin, shotDir+TPoint(mx,my), 20 );
  309.     }
  310.  
  311.     virtual const char *DebugInfo() { return "Ship"; }
  312.  
  313.   private:
  314.     int angle,radius,thrust;
  315. };
  316.  
  317. // Message -- a sprite that can display numbers 0-9, used for score display
  318. //
  319. class Message: public Sprite {
  320.   char *text;
  321.   uint  bufferLen;
  322. public:
  323.   Message( const TPoint& aOrigin, int aBufferLen );
  324.   ~Message();
  325.   void SetText( const char *aText ) {
  326.     if (strlen(aText) < bufferLen)
  327.       strcpy(text, aText);
  328. //    delete[] text;
  329. //    bufferLen = strlen(aText)+1;
  330. //    text = new char[bufferLen];
  331.   }
  332.   virtual void Draw( TMemoryDC& dc );
  333.   virtual const char *DebugInfo();
  334. };
  335.  
  336. #endif // SPRITE_H
  337.