home *** CD-ROM | disk | FTP | other *** search
-
- #import "NXIAlien.h"
- #import "NXIAlienOverseer.h"
-
- static id overseer = nil;
-
- @implementation NXIAlienOverseer
-
- + new
- { // this is hokey -- don't try to subclass it!
- if (!overseer) overseer = [[self alloc] init];
- return overseer;
- }
-
- - init
- { // we keep the dead state; this actor is never rendered. It's a "behind
- // the scenes" player...
- id ret = [super init];
- invaderList = [[List alloc] init];
- GK_CLEAR_VECTOR(&lastMovementDirection);
- GK_CLEAR_VECTOR(&movementDirection);
- GK_CLEAR_VECTOR(&movement);
- leftMost = nil; rightMost = nil;
- return ret;
- }
-
- - setUpAliensForLevel:(int)aLevel
- {
- id manager = [stage stageManager];
- int i, j, offset; NXRect bounds;
- [[stage bufferType:GK_SCREEN_BUFFER] getBounds:&bounds];
- offset = (NX_WIDTH(&bounds) / ALIEN_VERTICAL_STEP_SIZE) - aLevel;
- if (offset < 5) offset = 5;
- GK_SET_VECTOR(&movementDirection, ALIEN_RIGHT, 0.0);
- GK_SET_VECTOR(&lastMovementDirection, ALIEN_RIGHT, 0.0);
- // build up all the aliens and add them to the stage
- moveCycles = ALIEN_STEPCYCLES - aLevel;
- if (moveCycles < 1) moveCycles = 1;
- for (j = 0; j < ALIEN_NUMROWS; j++) { // work from top to bottom row
- // this code to get the color will allow me to change ALIEN_NUMROWS...
- float m = (j * 5.0 / ALIEN_NUMROWS);
- int color = BLUE_ALIEN;
- if (m > 0.99) color = GREEN_ALIEN;
- if (m > 2.99) color = RED_ALIEN;
- for (i = 0; i < ALIEN_NUMVADERS; i++) {
- id newVader = [manager getActorOfClass:[NXIAlien class]];
- NXPoint newPosition = { ALIEN_WIDTH * i,
- ALIEN_VERTICAL_STEP_SIZE * (offset - j) };
-
- [newVader initAlienColor:color at:&newPosition];
- [stage addActor:newVader ofType:GK_DYNAMIC_ACTOR];
- [invaderList addObject:newVader];
- // need to set up the collision group (player's bullets)
- // *****
- } }
- [self findRightMost];
- [self findLeftMost];
- return self;
- }
-
- - findRightMost
- { // find the rightmost alien invader
- int i; float x = 0.0;
- for (i=0; i<[invaderList count]; i++) {
- NXPoint aPoint; id vader = [invaderList objectAt:i];
- [vader at:(&aPoint)];
- if (aPoint.x > x) {
- x = aPoint.x;
- rightMost = vader;
- }
- }
- return self;
- }
-
- - findLeftMost
- { // find the leftmost alien invader
- int i; float x = 20000.0; // any really big number will do
- for (i=0; i<[invaderList count]; i++) {
- NXPoint aPoint; id vader = [invaderList objectAt:i];
- [vader at:(&aPoint)];
- if (aPoint.x < x) {
- x = aPoint.x;
- leftMost = vader;
- }
- }
- return self;
- }
-
- - alienLeavingTheStage:anAlien
- {
- if (anAlien == rightMost) [self findRightMost];
- if (anAlien == leftMost) [self findLeftMost];
- [invaderList removeObject:anAlien];
- switch ([invaderList count]) { // these are when we speed up
- case 32: case 16: case 8:
- case 4: case 2: case 1:
- moveCycles /= 2; break;
- }
- if (moveCycles < 1) moveCycles = 1; // fastest we can go!
- if (![invaderList count]) {
- // no more left: time to move to the next level!
- [[NXApp delegate] nextLevel];
- }
- return self;
- }
-
- - move:sender
- {
- // check to see if any invaders are past the "threshold"; if they are,
- // then we change the movement direction and move them all down.
- cycles++; // never gets inc'ed by GKActor machinery since we're "dead"
- if (cycles >= moveCycles) {
- cycles = 0;
- // see if we need to change directions or not:
- // if we moved down, it's time to reverse direction.
- if (GK_VECTOR_Y(&movementDirection) != 0.0) {
- GK_COPY_VECTORS(&movementDirection, &lastMovementDirection);
- GK_VECTOR_X(&movementDirection) *= -1;
- } else // if we're past the "edge" it's time to move down
- if (((movementDirection.x > 0) && [leftMost hitEdge:LEFT_EDGE]) ||
- ((movementDirection.x < 0) && [rightMost hitEdge:RIGHT_EDGE])) {
- GK_SET_VECTOR(&movementDirection, 0.0, -ALIEN_VERTICAL_STEP_SIZE);
- }
- GK_COPY_VECTORS(&movement, &movementDirection);
- // ***** play the marching sound here
- } else { // don't move; we're between steps
- GK_CLEAR_VECTOR(&movement);
- }
- return self;
- }
-
- - movementVector:(NXPoint *)aVector
- {
- GK_VECTOR_X(aVector) = GK_VECTOR_X(&movement);
- GK_VECTOR_Y(aVector) = GK_VECTOR_Y(&movement);
- return self;
- }
-
- @end
-