home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / demo4 / actor.cpp next >
Encoding:
C/C++ Source or Header  |  2000-09-12  |  4.3 KB  |  212 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    CActor
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    06/05/00
  8. //
  9. // Base:    None
  10. //
  11. // Derived:    CShip
  12. //            CAlien
  13. //            CBullet
  14. //            CPickup
  15. //
  16. //-------------------------------------------------------------
  17.  
  18. #include "demo4.h"
  19.  
  20. //-------------------------------------------------------------
  21.  
  22. CActor::CActor()
  23. {
  24.     m_scene = 0;
  25.     m_owner = 0;
  26.     m_is_active = false;
  27.     m_is_on_screen = false;
  28.     m_is_hit = false;
  29.     m_score_multiplier = 1.f;
  30. }
  31.  
  32. //-------------------------------------------------------------
  33.  
  34. CActor::~CActor()
  35. {
  36. }
  37.  
  38. //-------------------------------------------------------------
  39.  
  40. bool CActor::activate()
  41. {
  42.     if (!m_is_active) {
  43.     
  44.         const ActorInfo& info = getActorInfo();
  45.  
  46.         if (info.m_filename)
  47.             m_image = m_scene->getImage(info.m_filename);
  48.         else
  49.             m_image = 0;
  50.  
  51.         m_sprite.setImage(m_image);
  52.         m_sprite.setHotspot(gsCPoint(info.m_hotspot_x,
  53.                                      info.m_hotspot_y));
  54.         m_sprite.setActive(m_image != 0);
  55.  
  56.         m_shield = info.m_initial_shield;
  57.  
  58.         m_is_active = true;
  59.         m_is_on_screen = false;
  60.         m_is_hit = false;
  61.         }
  62.  
  63.     return true;
  64. }
  65.  
  66. //-------------------------------------------------------------
  67.  
  68. void CActor::kill()
  69. {
  70.     m_is_active = false;
  71. }
  72.  
  73. //-------------------------------------------------------------
  74.  
  75. void CActor::explode()
  76. {
  77.     if (m_image) {
  78.         gsCPoint size = m_image->getTileSize();
  79.  
  80.         int area = size.getX() * size.getY();
  81.  
  82.         CExplosion *x;
  83.  
  84.         if (area <= 32 * 32)
  85.             x = new CSmallExplosion;
  86.         else if (area <= 64 * 64)
  87.             x = new CMediumExplosion;
  88.         else
  89.             x = new CBigExplosion;
  90.  
  91.         m_scene->addActor(x);
  92.         x->setPosition(getPosition());
  93.         x->activate();
  94.         }
  95. }
  96.         
  97. //-------------------------------------------------------------
  98.  
  99. void CActor::registerHit(int energy,CActor *hitter)
  100. {
  101.     if (m_shield != INFINITE_SHIELD) {
  102.         if (m_shield > 0) {
  103.             m_shield -= energy;
  104.             if (m_shield <= 0) {
  105.                 m_shield = 0;
  106.                 onKilled();
  107.                 }
  108.             }
  109.  
  110.         m_is_hit = true;
  111.         m_hit_timer.start();
  112.         }
  113. }
  114.  
  115. //-------------------------------------------------------------
  116.  
  117. void CActor::onKilled()
  118. {
  119. }
  120.  
  121. //-------------------------------------------------------------
  122.  
  123. bool CActor::draw()
  124. {
  125.     if (isActive() && m_image) {
  126.         m_sprite.setPosition(gsCPoint(m_position) + m_scene->getMap()->getPosition());
  127.  
  128.         if (m_is_hit) {
  129.             if (m_hit_timer.getTime() > ACTOR_HIT_TIME) {
  130.                 m_hit_timer.reset();
  131.                 m_is_hit = false;
  132.                 }
  133.             }
  134.  
  135.         if (m_is_hit) {
  136.             int level = (int) (255.f * (1.f - m_hit_timer.getTime() / ACTOR_HIT_TIME));
  137.             m_sprite.enableFillColour(gsCColour(level,level,level));
  138.             }
  139.         else
  140.             m_sprite.disableFillColour();
  141.  
  142.         bool was_on_screen = m_is_on_screen;
  143.  
  144.         m_is_on_screen = m_sprite.draw();
  145.  
  146.         if (was_on_screen && !m_is_on_screen)
  147.             onLeavingScreen();
  148.  
  149.         if (m_is_on_screen)
  150.             m_scene->addToCollisionList(this,getCollisionRect());
  151.         }
  152.  
  153.     return true;
  154. }
  155.  
  156. //-------------------------------------------------------------
  157. // animate over range of frames
  158.  
  159. bool CActor::animate(AnimationMode mode,int first_frame,int num_frames)
  160. {
  161.     bool finished = false;
  162.  
  163.     int frame;
  164.  
  165.     if (num_frames <= 1)
  166.         frame = 0;
  167.     else {
  168.         frame = (int) (m_timer.getTime() * getActorInfo().m_anim_rate);
  169.  
  170.         switch (mode) {
  171.             case ANIMATE_LOOP:
  172.                 frame = frame % (num_frames - 1);    // cycle repeatedly
  173.                 break;
  174.             case ANIMATE_ONESHOT:
  175.                 if (frame >= num_frames) {
  176.                     frame = num_frames - 1;            // stay on last frame
  177.                     finished = true;                // flag that we've finished
  178.                     }
  179.                 break;
  180.             }
  181.         }
  182.  
  183.     m_sprite.setFrame(first_frame + frame);
  184.  
  185.     return finished;
  186. }
  187.  
  188. //-------------------------------------------------------------
  189. // animate over entire range
  190.  
  191. bool CActor::animate(AnimationMode mode)
  192. {
  193.     return animate(mode,0,m_image->getNumTiles());
  194. }
  195.  
  196. //-------------------------------------------------------------
  197. // Convert velocity into a direction (0..num_dir-1)
  198.  
  199. int CActor::getDirection(int num_dir)
  200. {
  201.     if (m_velocity.length() == 0.f)
  202.         return 0;
  203.  
  204.     float angle = m_velocity.direction();
  205.  
  206.     float step = 360.f / (float) num_dir;
  207.     
  208.     return ((int) ((angle - step / 2.f + 360.f) / step)) & (num_dir - 1);
  209. }
  210.  
  211. //-------------------------------------------------------------
  212.