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

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    CScene
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    06/05/00
  8. //
  9. // Base:    None
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "demo4.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. CScene::CScene()
  20. {
  21.     m_frame_count = 0;
  22.     m_map = 0;
  23.     m_checkpoint_active = false;
  24.     m_is_warping = false;
  25. }
  26.  
  27. //-------------------------------------------------------------
  28.  
  29. CScene::~CScene()
  30. {
  31. }
  32.  
  33. //-------------------------------------------------------------
  34.  
  35. gsCTiledImage *CScene::getImage(const char *filename)
  36. {
  37.     if (filename == 0)
  38.         return 0;
  39.  
  40.     for (int i = 0; i < m_image_list.getSize(); i++) {
  41.         if (strcmp(m_image_list[i]->m_filename,filename) == 0)
  42.             return &m_image_list[i]->m_image;
  43.         }
  44.  
  45.     ImageEntry *image_entry = new ImageEntry;
  46.  
  47.     strcpy(image_entry->m_filename,filename);
  48.  
  49.     gsCFile::setDirectory(DIRECTORY_GRAPHICS);
  50.  
  51.     if (image_entry->m_image.load(filename)) {
  52.         m_image_list.addItem(image_entry);
  53.         return &image_entry->m_image;
  54.         }
  55.     else {
  56.         delete image_entry;
  57.         return 0;
  58.         }
  59. }
  60.  
  61. //-------------------------------------------------------------
  62.  
  63. bool CScene::loadImages()
  64. {
  65.     for (int i = 0; i < INFO_TOTAL; i++) {
  66.         gsCTiledImage *image = getImage(ActorInfoList[i].m_filename);
  67.  
  68.         if (image) {
  69.             image->setTileSize(gsCPoint(ActorInfoList[i].m_tile_width,
  70.                                         ActorInfoList[i].m_tile_height));
  71.  
  72.             image->enableColourKey(gsCColour(gsMAGENTA));
  73.             }
  74.         }
  75.  
  76.     return true;
  77. }
  78.  
  79. //-------------------------------------------------------------
  80.  
  81. void CScene::addToCollisionList(CActor *actor,const gsCRect& rect)
  82. {
  83.     switch (actor->getActorInfo().m_type) {
  84.         case ACTOR_TYPE_SHIP:
  85.             if (m_ship_is_cloaked)
  86.                 break;
  87.             m_collision_list.addObject((void *) actor,
  88.                                       rect,
  89.                                       (1 << ACTOR_TYPE_SHIP),
  90.                                       (1 << ACTOR_TYPE_PICKUP) | (1 << ACTOR_TYPE_ALIEN));
  91.             break;
  92.         case ACTOR_TYPE_UPGRADE:
  93.             if (m_ship_is_cloaked)
  94.                 break;
  95.             m_collision_list.addObject((void *) actor,
  96.                                       rect,
  97.                                       (1 << ACTOR_TYPE_UPGRADE),
  98.                                       (1 << ACTOR_TYPE_PICKUP) | (1 << ACTOR_TYPE_ALIEN));
  99.             break;
  100.         case ACTOR_TYPE_BULLET:
  101.             m_collision_list.addObject((void *) actor,
  102.                                       rect,
  103.                                       (1 << ACTOR_TYPE_BULLET),
  104.                                       (1 << ACTOR_TYPE_ALIEN) | (1 << ACTOR_TYPE_ALIENBULLET));
  105.             break;
  106.         case ACTOR_TYPE_ALIENBULLET:
  107.             m_collision_list.addObject((void *) actor,
  108.                                       rect,
  109.                                       (1 << ACTOR_TYPE_ALIENBULLET),
  110.                                       (1 << ACTOR_TYPE_SHIP));
  111.             break;
  112.         case ACTOR_TYPE_ALIEN:
  113.             m_collision_list.addObject((void *) actor,
  114.                                       rect,
  115.                                       (1 << ACTOR_TYPE_ALIEN),
  116.                                       0);
  117.             break;
  118.         case ACTOR_TYPE_PICKUP:
  119.             m_collision_list.addObject((void *) actor,
  120.                                       rect,
  121.                                       (1 << ACTOR_TYPE_PICKUP),
  122.                                       0);
  123.             break;
  124.         case ACTOR_TYPE_WEAPON:
  125.         case ACTOR_TYPE_ENGINE:
  126.         case ACTOR_TYPE_LABEL:
  127.         case ACTOR_TYPE_EFFECT:
  128.             // no collision detection
  129.             break;
  130.         }
  131. }
  132.  
  133. //-------------------------------------------------------------
  134.  
  135. void CScene::updateActorsOfType(ActorType type,Controls *controls)
  136. {
  137.     for (int j = 0; j < m_actor_list.getSize(); j++) {
  138.         CActor *obj = m_actor_list[j];
  139.         if (obj->isActive() &&
  140.             obj->getActorInfo().m_type == type)
  141.             obj->update(controls);
  142.         }
  143. }
  144.  
  145. //-------------------------------------------------------------
  146.  
  147. void CScene::updateAllActors(Controls *controls)
  148. {
  149.     updateActorsOfType(ACTOR_TYPE_SHIP,controls);
  150.     updateActorsOfType(ACTOR_TYPE_UPGRADE,controls);
  151.     updateActorsOfType(ACTOR_TYPE_ALIEN,controls);
  152.     updateActorsOfType(ACTOR_TYPE_WEAPON,controls);
  153.     updateActorsOfType(ACTOR_TYPE_ENGINE,controls);
  154.     updateActorsOfType(ACTOR_TYPE_ALIENBULLET,controls);
  155.     updateActorsOfType(ACTOR_TYPE_BULLET,controls);
  156.     updateActorsOfType(ACTOR_TYPE_PICKUP,controls);
  157.     updateActorsOfType(ACTOR_TYPE_LABEL,controls);
  158.     updateActorsOfType(ACTOR_TYPE_EFFECT,controls);
  159. }
  160.  
  161. //-------------------------------------------------------------
  162.  
  163. void CScene::drawActorsOfType(ActorType type,int total)
  164. {
  165.     for (int j = 0; j < total; j++) {
  166.         CActor *actor = m_actor_list[j];
  167.         if (actor->isActive() &&
  168.             actor->getActorInfo().m_type == type)
  169.             actor->draw();
  170.         }
  171. }
  172.  
  173. //-------------------------------------------------------------
  174.  
  175. void CScene::actorCollisionCallback(void *object1,void *object2)
  176. {
  177.     gsASSERT(object1);
  178.     gsASSERT(object2);
  179.     
  180.     CActor *actor1 = (CActor *) object1;
  181.     CActor *actor2 = (CActor *) object2;
  182.  
  183.     if (!actor1->isActive() ||
  184.         !actor2->isActive())
  185.         return;
  186.  
  187.     actor1->onCollisionWithActor(actor2);
  188. }
  189.  
  190. //-------------------------------------------------------------
  191. // Draw all active game actors - prioritized
  192.  
  193. void CScene::drawAllActors(gsCMap *map)
  194. {
  195.     m_frame_count++;
  196.     
  197.     m_collision_list.clear();
  198.  
  199.     int total = m_actor_list.getSize();
  200.  
  201.     CShip *ship = findShip();
  202.  
  203.     map->draw();
  204.  
  205.     drawActorsOfType(ACTOR_TYPE_EFFECT,total);
  206.     drawActorsOfType(ACTOR_TYPE_PICKUP,total);
  207.     drawActorsOfType(ACTOR_TYPE_ALIEN,total);
  208.     drawActorsOfType(ACTOR_TYPE_ALIENBULLET,total);
  209.     drawActorsOfType(ACTOR_TYPE_BULLET,total);
  210.     drawActorsOfType(ACTOR_TYPE_ENGINE,total);
  211.     drawActorsOfType(ACTOR_TYPE_SHIP,total);
  212.     drawActorsOfType(ACTOR_TYPE_UPGRADE,total);
  213.     drawActorsOfType(ACTOR_TYPE_WEAPON,total);
  214.     drawActorsOfType(ACTOR_TYPE_LABEL,total);
  215. }
  216.  
  217. //-------------------------------------------------------------
  218.  
  219. void CScene::checkActorCollisions()
  220. {
  221.     m_collision_list.scan(actorCollisionCallback);
  222.  
  223.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  224.         if (m_actor_list[i]->isActive())
  225.             m_actor_list[i]->postProcessCollision();
  226.         }
  227. }
  228.  
  229. //-------------------------------------------------------------
  230.  
  231. void CScene::checkMapCollisions(gsCMap *map)
  232. {
  233.     // check for collisions between actors and map
  234.  
  235.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  236.         CActor *actor = m_actor_list[i];
  237.         if (actor->isActive()) {
  238.             switch (actor->getActorInfo().m_type) {
  239.                 case ACTOR_TYPE_SHIP:
  240.                 case ACTOR_TYPE_UPGRADE:
  241.                     if (m_ship_is_cloaked)
  242.                         break;
  243.                     {
  244.                         gsCRect rect = actor->getCollisionRect();
  245.                         rect.move(-map->getPosition());
  246.                         int hits = map->hitBy(rect,COLLIDE_WITH_SHIP);
  247.                         if (hits)
  248.                             actor->onCollisionWithMap(map,hits);
  249.                     }
  250.                     break;
  251.  
  252.                 case ACTOR_TYPE_BULLET:
  253.                 case ACTOR_TYPE_ALIENBULLET:
  254.                     {
  255.                         gsCRect rect = actor->getCollisionRect();
  256.                         rect.move(-map->getPosition());
  257.                         int hits = map->hitBy(rect,COLLIDE_WITH_BULLETS);
  258.                         if (hits)
  259.                             actor->onCollisionWithMap(map,hits);
  260.                     }
  261.                     break;
  262.                 }
  263.             }
  264.         }
  265. }
  266.  
  267. //-------------------------------------------------------------
  268.  
  269. void CScene::removeDeadActors()
  270. {
  271.     for (int i = m_actor_list.getSize() - 1; i >= 0; i--) {
  272.         if (!m_actor_list[i]->isActive()) {
  273.             delete m_actor_list[i];
  274.             m_actor_list.removeIndex(i);
  275.             }
  276.         }
  277. }
  278.  
  279. //-------------------------------------------------------------
  280.  
  281. void CScene::killAllActors()
  282. {
  283.     int i;
  284.     
  285.     for (i = 0; i < m_actor_list.getSize(); i++)
  286.         m_actor_list[i]->kill();
  287.  
  288.     for (i = 0; i < m_actor_list.getSize(); i++)
  289.         delete m_actor_list[i];
  290.  
  291.     m_actor_list.clear();
  292. }
  293.  
  294. //-------------------------------------------------------------
  295.  
  296. void CScene::destroyAll()
  297. {
  298.     int i;
  299.  
  300.     for (i = 0; i < m_actor_list.getSize(); i++)
  301.         delete m_actor_list[i];
  302.  
  303.     m_actor_list.clear();
  304.  
  305.     for (i = 0; i < m_image_list.getSize(); i++) {
  306.         m_image_list[i]->m_image.destroy();
  307.         delete m_image_list[i];
  308.         }
  309.     
  310.     m_image_list.clear();
  311. }
  312.  
  313. //-------------------------------------------------------------
  314.  
  315. CShip *CScene::findShip()
  316. {
  317.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  318.         if (m_actor_list[i]->getActorInfo().m_type == ACTOR_TYPE_SHIP)
  319.             return (CShip *) m_actor_list[i];
  320.         }
  321.  
  322.     return 0;
  323. }
  324.  
  325. //-------------------------------------------------------------
  326.  
  327. void CScene::createMapExplosion(gsCMap *map,const gsCPoint& position)
  328. {
  329.     CSmallExplosion *exp = new CSmallExplosion();
  330.     addActor(exp);
  331.  
  332.     gsCPoint tile_size = map->getImage()->getTileSize();
  333.     gsCPoint tile_centre = tile_size / gsCPoint(2,2);
  334.  
  335.     gsCPoint pos = position * tile_size + tile_centre;
  336.     exp->setPosition(gsCVector((float) pos.getX(),(float) pos.getY()));
  337.     exp->activate();
  338. }
  339.  
  340. //-------------------------------------------------------------
  341.  
  342. CActor *CScene::getActor(int index)
  343. {
  344.     return m_actor_list[index];
  345. }
  346.  
  347. //-------------------------------------------------------------
  348.  
  349. CActor *CScene::findNearestActor(ActorType type,const gsCVector& position,int dir)
  350. {
  351.     CActor *nearest_actor = 0;
  352.     float nearest_distance = 99999.f;
  353.  
  354.     for (int i = 0; i < m_actor_list.getSize(); i++) {
  355.         CActor *actor = m_actor_list[i];
  356.         if (actor->isActive() &&
  357.             actor->getActorInfo().m_type == type) {
  358.             if (dir != 0) {
  359.                 float sy = position.getY();
  360.                 float ay = actor->getPosition().getY();
  361.                 if (dir < 0 && sy < ay)
  362.                     continue;
  363.                 if (dir > 0 && sy > ay)
  364.                     continue;
  365.                 }
  366.             float d = (actor->getPosition() - position).length();
  367.             if (nearest_actor == 0 ||
  368.                 d < nearest_distance) {
  369.                 nearest_actor = actor;
  370.                 nearest_distance = d;
  371.                 }
  372.             }
  373.         }
  374.  
  375.     return nearest_actor;
  376. }
  377.  
  378. //-------------------------------------------------------------
  379.  
  380.