float STARTY = -100; int PRELUDE_FALLS = 5; class Fleet { int counter = 0; float x, y; HashSet invaders = new HashSet(); float left; float right; float bottom; float fleetwidth; int needToTouch = RIGHT; int mincol,maxcol,minrow,maxrow; int framecounter = 0; Fleet() { x = 20; y = STARTY; for(int r = 0; r < FLEET_ROWS ; r++) { for(int c = 0; c < FLEET_COLS; c++) { invaders.add(new Invader(0,0,this,r,c)); } } updateInvaders(); } boolean landed(){ if(bottom > TANK_STARTY ){ return true; } else { return false; } } //figure out the width of the thing, the actual left and right side void computeSides(){ boolean first = true; for(Invader i : invaders){ if(! i.attacking){ // i.identify(); if(first){ left = i.x - INVADER_OFFSET_X; right = i.x + INVADER_WIDTH + INVADER_OFFSET_X; bottom = i.y + INVADER_HEIGHT + INVADER_OFFSET_Y; mincol = i.col; maxcol = i.col; minrow = i.row; maxrow = i.row; first = false; } left = min(left,i.x - INVADER_OFFSET_X); right = max(right,i.x + INVADER_WIDTH+ INVADER_OFFSET_X); bottom = max(bottom, i.y + INVADER_HEIGHT + INVADER_OFFSET_Y); mincol = min(mincol,i.col); maxcol = max(maxcol,i.col); minrow = min(minrow,i.row); maxrow = max(maxrow,i.row); } } fleetwidth = right - left; // println(maxrow); } //put all the invaders correct relative to the location of the whole fleet void updateInvaders(){ for(Invader i : invaders){ i.doOffset(); //formation //i.checkCollisions(); //now legions of invaders don't kill buildings //i.checkHitTank(); //now invaders in formation don't kill tank } computeSides(); } void animateInvaders(){ for(Invader i : invaders){ i.advanceFrame(); } computeSides(); } void removeAll(Set killed){ invaders.removeAll(killed); } void move(){ framecounter++; if(framecounter == 40){ animateInvaders(); framecounter = 0; } } void handleKey(int keyCode){ if(keyCode == LEFT){ x-= FLEET_SIDEMOVE; } if(keyCode == RIGHT){ x+=FLEET_SIDEMOVE; } if(DEBUG == 1 && keyCode == DOWN){ descend(); } updateInvaders(); computeSides(); fixLeft(); fixRight(); if(keyCode == 32){ //launch a random fighter from the bottom row if(hasInvadersInFormation()){ fxDivebomb(); launchRandomFromRow(maxrow); } } updateInvaders(); } boolean onDeck = false; void march(){ if(frameCount % 3 != 0 && (!isKeyDown(83))){ return; } if(onDeck) return; if(needToTouch == LEFT){ x-= FLEET_SIDEMOVE; } if(needToTouch == RIGHT){ x+=FLEET_SIDEMOVE; } updateInvaders(); computeSides(); fixRight(); fixLeft(); if(y > STARTY + (FLEET_DOWNMOVE * PRELUDE_FALLS)){ onDeck = true; } updateInvaders(); } void fixRight(){ if(right >= width){ x -= (right - width); if(needToTouch == RIGHT){ needToTouch = LEFT; descend(); } } updateInvaders(); } void fixLeft(){ if(left <= 0){ x -= left; if(needToTouch == LEFT){ needToTouch = RIGHT; descend(); } } } void descend(){ // println("GO DOWN"); y += FLEET_DOWNMOVE; if(onDeck){ numberOfFallsByPlayer++; } } int numberOfFallsByPlayer = 0; boolean hasDroppedOnce = false; void launchRandomFromRow(int whatrow){ hasDroppedOnce = true; ArrayList candidates = new ArrayList(); for(Invader i : invaders){ if(! i.attacking && i.row == whatrow){ candidates.add(i); } } if(candidates.size() == 0){ return; } int pick = (int)Math.floor(random(candidates.size())); Invader poorGuy = candidates.get(pick); launchInvader(poorGuy); } void launchInvader(Invader poorGuy){ invaders.remove(poorGuy); invadersAttacking.add(poorGuy); poorGuy.attack(); } boolean hasInvadersInFormation(){ for(Invader i : invaders){ if(!i.attacking) { return true; } } return false; } void draw(){ stroke(255); /*line(0,0,x,y); line(0,height,left,y); line(width,height,right,y);*/ for(Invader i : invaders){ i.draw(); } } }