home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / GameKit / Examples / NX_Invaders / NXIAlienOverseer.m < prev    next >
Encoding:
Text File  |  1994-06-07  |  4.0 KB  |  140 lines

  1.  
  2. #import "NXIAlien.h"
  3. #import "NXIAlienOverseer.h"
  4.  
  5. static id overseer = nil;
  6.  
  7. @implementation NXIAlienOverseer
  8.  
  9. + new
  10. {    // this is hokey -- don't try to subclass it!
  11.     if (!overseer) overseer = [[self alloc] init];
  12.     return overseer;
  13. }
  14.  
  15. - init
  16. {    // we keep the dead state; this actor is never rendered.  It's a "behind
  17.     // the scenes" player...
  18.     id ret = [super init];
  19.     invaderList = [[List alloc] init];
  20.     GK_CLEAR_VECTOR(&lastMovementDirection);
  21.     GK_CLEAR_VECTOR(&movementDirection);
  22.     GK_CLEAR_VECTOR(&movement);
  23.     leftMost = nil; rightMost = nil;
  24.     return ret;
  25. }
  26.  
  27. - setUpAliensForLevel:(int)aLevel
  28. {
  29.     id manager = [stage stageManager];
  30.     int i, j, offset; NXRect bounds;
  31.     [[stage bufferType:GK_SCREEN_BUFFER] getBounds:&bounds];
  32.     offset = (NX_WIDTH(&bounds) / ALIEN_VERTICAL_STEP_SIZE) - aLevel;
  33.     if (offset < 5) offset = 5;
  34.     GK_SET_VECTOR(&movementDirection, ALIEN_RIGHT, 0.0);
  35.     GK_SET_VECTOR(&lastMovementDirection, ALIEN_RIGHT, 0.0);
  36.     // build up all the aliens and add them to the stage
  37.     moveCycles = ALIEN_STEPCYCLES - aLevel;
  38.     if (moveCycles < 1) moveCycles = 1;
  39.     for (j = 0; j < ALIEN_NUMROWS; j++) { // work from top to bottom row
  40.     // this code to get the color will allow me to change ALIEN_NUMROWS...
  41.         float m = (j * 5.0 / ALIEN_NUMROWS);
  42.         int color = BLUE_ALIEN;
  43.         if (m > 0.99) color = GREEN_ALIEN;
  44.         if (m > 2.99) color = RED_ALIEN;
  45.         for (i = 0; i < ALIEN_NUMVADERS; i++) {
  46.             id newVader = [manager getActorOfClass:[NXIAlien class]];
  47.             NXPoint newPosition = { ALIEN_WIDTH * i,
  48.                     ALIEN_VERTICAL_STEP_SIZE * (offset - j) };
  49.             
  50.             [newVader initAlienColor:color at:&newPosition];
  51.             [stage addActor:newVader ofType:GK_DYNAMIC_ACTOR];
  52.             [invaderList addObject:newVader];
  53.             // need to set up the collision group (player's bullets)
  54.             // *****
  55.     }    }
  56.     [self findRightMost];
  57.     [self findLeftMost];
  58.     return self;
  59. }
  60.  
  61. - findRightMost
  62. {    // find the rightmost alien invader
  63.     int i; float x = 0.0;
  64.     for (i=0; i<[invaderList count]; i++) {
  65.         NXPoint aPoint; id vader = [invaderList objectAt:i];
  66.         [vader at:(&aPoint)];
  67.         if (aPoint.x > x) {
  68.             x = aPoint.x;
  69.             rightMost = vader;
  70.         }
  71.     }
  72.     return self;
  73. }
  74.  
  75. - findLeftMost
  76. {    // find the leftmost alien invader
  77.     int i; float x = 20000.0; // any really big number will do
  78.     for (i=0; i<[invaderList count]; i++) {
  79.         NXPoint aPoint; id vader = [invaderList objectAt:i];
  80.         [vader at:(&aPoint)];
  81.         if (aPoint.x < x) {
  82.             x = aPoint.x;
  83.             leftMost = vader;
  84.         }
  85.     }
  86.     return self;
  87. }
  88.  
  89. - alienLeavingTheStage:anAlien
  90. {
  91.     if (anAlien == rightMost) [self findRightMost];
  92.     if (anAlien == leftMost) [self findLeftMost];
  93.     [invaderList removeObject:anAlien];
  94.     switch ([invaderList count]) { // these are when we speed up
  95.         case 32:    case 16:    case 8:
  96.         case 4:        case 2:        case 1:
  97.             moveCycles /= 2; break;
  98.     }
  99.     if (moveCycles < 1) moveCycles = 1;    // fastest we can go!
  100.     if (![invaderList count]) {
  101.         // no more left:  time to move to the next level!
  102.         [[NXApp delegate] nextLevel];
  103.     }
  104.     return self;
  105. }
  106.  
  107. - move:sender
  108. {
  109.     // check to see if any invaders are past the "threshold"; if they are,
  110.     // then we change the movement direction and move them all down.
  111.     cycles++;    // never gets inc'ed by GKActor machinery since we're "dead"
  112.     if (cycles >= moveCycles) {
  113.         cycles = 0;
  114.         // see if we need to change directions or not:
  115.         // if we moved down, it's time to reverse direction.
  116.         if (GK_VECTOR_Y(&movementDirection) != 0.0) {
  117.             GK_COPY_VECTORS(&movementDirection, &lastMovementDirection);
  118.             GK_VECTOR_X(&movementDirection) *= -1;
  119.         } else // if we're past the "edge" it's time to move down
  120.             if (((movementDirection.x > 0) && [leftMost hitEdge:LEFT_EDGE]) ||
  121.             ((movementDirection.x < 0) && [rightMost hitEdge:RIGHT_EDGE])) {
  122.             GK_SET_VECTOR(&movementDirection, 0.0, -ALIEN_VERTICAL_STEP_SIZE);
  123.         }
  124.         GK_COPY_VECTORS(&movement, &movementDirection);
  125.         // ***** play the marching sound here
  126.     } else {    // don't move; we're between steps
  127.         GK_CLEAR_VECTOR(&movement);
  128.     }
  129.     return self;
  130. }
  131.  
  132. - movementVector:(NXPoint *)aVector
  133. {
  134.     GK_VECTOR_X(aVector) = GK_VECTOR_X(&movement);
  135.     GK_VECTOR_Y(aVector) = GK_VECTOR_Y(&movement);
  136.     return self;
  137. }
  138.  
  139. @end
  140.