/** * nInvaders - a space invaders clone for ncurses * Copyright (C) 2002-2003 Dettus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * homepage: http://ninvaders.sourceforge.net * mailto: ninvaders-devel@lists.sourceforge.net * */ #include "aliens.h" #include "player.h" #include "nInvaders.h" /** * initialize aliens attributes */ void aliensReset() { int i,j; // three different types of aliens [5], [10] int level[ALIENS_MAX_NUMBER_Y][ALIENS_MAX_NUMBER_X]={ {1,1,1,1,1,1,1,1,1,1}, {2,2,2,2,2,2,2,2,2,2}, {2,2,2,2,2,2,2,2,2,2}, {3,3,3,3,3,3,3,3,3,3}, {3,3,3,3,3,3,3,3,3,3} }; aliensClear(aliens.posX, aliens.posY, aliens.right, aliens.bottom); // clear old position of aliens // reset alien position aliens.posX = 0; aliens.posY = 0; aliens.right = 0; aliens.bottom = 0; aliens.left = 0; aliens.speed = 1; // copy level-array to enemy-array for (i=0;ialiens.left) {aliens.left=-k;} if (aliens.right==-1 || k>aliens.right) {aliens.right=k;} if (aliens.bottom==-1 || c>aliens.bottom) {aliens.bottom=c;} } } } else { c++; } } aliens.bottom=aliens.bottom*2; // every 2nd row is an empty row aliens.left=aliens.left*3; // alien sprite is 3 chars wide aliens.right=aliens.right*3; // alien sprite is 3 chars wide // display remaining aliens with animation aliensRefresh(level, &alienBlock[0][0]); } /** * move aliens' missiles and do player/bunker hit testing * a zero value in alienshotx indicates that the appropriate missile is loaded, but not fired */ int aliensMissileMove() { int i, tmp; int fPlayerWasHit = 0; int shootThreshold; static int alienshot_counter = 0; // calculate threshold when next missile should be fired // it is done here to save calculation time in for-instruction shootThreshold = (skill_level * 8) * (shipnum + 2); alienshot_counter = alienshot_counter + 10 ; // loop all possible missiles for (i = 0; i < ALIENS_MAX_MISSILES; i++) { // if the current missile is flying we should do movements if (alienshotx[i] != 0) { aliensMissileClear(alienshotx[i],alienshoty[i]); // clear old position // if missile hit the bunkers if (bunkersHitCheck(alienshotx[i], alienshoty[i]) == 1) { alienshotx[i] = 0; // value of zero reloads missile } alienshoty[i]++; // move missile downwards // check if player was hit by an alien missile if (playerHitCheck(alienshotx[i], alienshoty[i]) == 1) { alienshotx[i] = 0; // value of zero reloads missile fPlayerWasHit = 1; } } else { // missile not launched yet // start new missile if counter says so if (alienshot_counter > shootThreshold && shipnum > 0) {// only shot if there's an alien left alienshot_counter = 0; // reset counter tmp = random() % ALIENS_MAX_NUMBER_X; // randomly select one of the ... while (lowest_ship[tmp] == -1) { // ...aliens at the bottom of ... tmp = random() % ALIENS_MAX_NUMBER_X; // ...a column to launch missile } alienshoty[i]=aliens.posY+lowest_ship[tmp]; // set y position of missile alienshotx[i]=aliens.posX+tmp*3; // set x position of missile } } // if // display missiles if still running or just launched; could have been modified in the above code if (alienshotx[i] != 0) { // if missile is out of battlefield if (alienshoty[i] == SCREENHEIGHT - 1) { alienshotx[i] = 0; // reload missile } else { aliensMissileDisplay(alienshotx[i], alienshoty[i]); // display Missile at new position } } } // for return fPlayerWasHit; } /** * check if missile hit an alien */ int aliensHitCheck(int shotx, int shoty) { int alienType = 0; int shipx, shipy; // if missile is within alien-rectangle if (shotx >= aliens.posX && shotx <= aliens.posX + ALIENS_MAX_NUMBER_X * 3 - 1 && shoty >= aliens.posY && shoty <= aliens.posY + (ALIENS_MAX_NUMBER_Y - 1) * 2) { // calculate the ship that was hit shipx = (shotx - aliens.posX) / 3; shipy = (shoty - aliens.posY) / 2; // if there is still a ship at this position alienType = alienBlock[shipy][shipx]; if (alienType != 0) { alienBlock[shipy][shipx] = 0; // delete alien ship } } return alienType; // returns 0 if no alien was hit, else returns type-code of alien } /** * check if missile hit an element of bunker */ int bunkersHitCheck(int shotx, int shoty) { int adjx, adjy; int fBunkerWasHit = 0; // if missile is within bunker-rectangle if (shotx >= BUNKERX && shotx < BUNKERX + BUNKERWIDTH && shoty >= BUNKERY && shoty < BUNKERY + BUNKERHEIGHT) { // calculate the element of the bunker that was hit adjy = shoty - BUNKERY; adjx = shotx - BUNKERX; // if there is still an element if(bunker[adjy][adjx] == 1){ bunker[adjy][adjx] = 0; // delete element fBunkerWasHit = 1; // bunker was hit! } } return fBunkerWasHit; }