/** * 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 "view.h" #include "globals.h" #include #include #include #define RED 1 #define GREEN 2 #define YELLOW 3 #define BLUE 4 #define CYAN 5 #define MAGENTA 6 #define WHITE 7 WINDOW *wBattleField; WINDOW *wEmpty; WINDOW *wScores; WINDOW *wPlayer; WINDOW *wPlayerMissile; WINDOW *wAliens; WINDOW *wAliensMissile; WINDOW *wBunkers; WINDOW *wGameOver; WINDOW *wUfo; WINDOW *wStatus; WINDOW *wTitleScreen; /** * initialize player sprites */ static void playerInit() { wPlayer = newpad(1, PLAYERWIDTH); // new pad with appropriate size wclear(wPlayer); // clear pad wattrset(wPlayer,COLOR_PAIR(YELLOW)); // set color waddstr(wPlayer,"/-^-\\"); // set sprite } /** * display player sprite */ void playerDisplay(int x, int y) { copywin(wPlayer,wBattleField,0,0,y,x,y,x+PLAYERWIDTH-1,0); } /** * clear player sprite */ void playerClear(int x, int y) { copywin(wEmpty,wBattleField,0,0,y,x,y,x+PLAYERWIDTH-1,0); } /** * initialize missile sprites */ static void playerMissileInit() { wPlayerMissile = newpad(1, 1); // new pad with appropriate size wclear(wPlayerMissile); // clear pad wattrset(wPlayerMissile,COLOR_PAIR(WHITE)); // set color waddch(wPlayerMissile,'!'); // set sprite wrefresh(wPlayerMissile); } /** * display missile sprite */ void playerMissileDisplay(int x, int y) { copywin(wPlayerMissile,wBattleField,0,0,y,x,y,x,0); } /** * clear missile sprite */ void playerMissileClear(int x, int y) { copywin(wEmpty,wBattleField,0,0,y,x,y,x,0); } /** * some explosion animation */ void playerExplosionDisplay(int x, int y) { WINDOW* wPlayerExplosion; char playerExplosionChars[16+1]="@~`.,^#*-_=\\/%{}"; int t,s; wPlayerExplosion=newpad(1,PLAYERWIDTH); // new pad wattrset(wPlayerExplosion,COLOR_PAIR(YELLOW)); // set color for(t=0;t<5;t++){ // 5 frames wclear(wPlayerExplosion); // clear pad for(s=0;s", "_x_", "*^*", "\\_/", "o o"}, {".-.", "-O_", "/o\\", "o-o", "", "-x-", "o^o", "/~\\", "oo "} }; int colors[9] = {RED, GREEN, BLUE, RED, YELLOW, WHITE, WHITE, YELLOW, RED}; wclear(wAliens); // clear pad wattrset(wAliens,COLOR_PAIR(RED)); // set color frame++; // next frame // draw alien if there is one for (row = 0; row < ALIENS_MAX_NUMBER_Y*2; row++) { for (k = 0; k < ALIENS_MAX_NUMBER_X; k++) { if ((row % 2) == 0) { // display aliens every even row alienType = *(pAliens + c * (ALIENS_MAX_NUMBER_X) + k); // get type of alien //alienBlock[c][k] if (alienType != 0) { // if there is an alien to display wattrset(wAliens,COLOR_PAIR(colors[alienType-1])); // set color waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][0]); // set char1 waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][1]); // set char2 waddch(wAliens,ships[frame%2][alienType-1+(3*((level-1)%3))][2]); // set char3 if (alienType > 4) { *(pAliens + c * ALIENS_MAX_NUMBER_X + k) = (alienType + 1) % 9; } // todo: what's that? If alien_type > 4 then do a modulo operation??? } else { waddstr(wAliens," "); // no alien } } else { waddstr(wAliens," "); // no aliens at odd rows } } if ((row % 2) == 1) {c++;} // goto next row at alienblock } } /** * initialize bunkers sprites */ static void bunkersInit() { wBunkers = newpad(BUNKERHEIGHT, BUNKERWIDTH); // new pad data wclear(wBunkers); } /** * display bunkers sprite * needs pointer to bunker-array */ void bunkersDisplay(int *pBunker) { int l, k; wclear(wBunkers); wattrset(wBunkers,COLOR_PAIR(CYAN)); for (l=0;l", "", "", "< oo>"}; static int frame = 0; wclear(wUfo); wattrset(wUfo, COLOR_PAIR(MAGENTA)); waddstr(wUfo, ufo[frame % 4]); frame++; } /** * initialize ufo sprite */ static void ufoInit() { wUfo = newpad(1, UFOWIDTH); // new pad with appropriate size wclear(wUfo); // clear pad wattrset(wUfo, COLOR_PAIR(MAGENTA)); // set color } /** * display ufo sprite */ void ufoDisplay(int x, int y) { copywin(wUfo, wBattleField, 0, 0, y, x, y, x + UFOWIDTH - 1, 0); } /** * clear ufo sprite */ void ufoClear(int x, int y) { copywin(wEmpty, wBattleField, 0, 0, y, x, y, x + UFOWIDTH - 1, 0); } /** * initialize gameover graphic */ static void gameOverInit() { // init game-over banner wGameOver = newpad(13, 31); wclear(wGameOver); wattrset(wGameOver, COLOR_PAIR(WHITE)); waddstr(wGameOver, " "); waddstr(wGameOver, " ##### #### ## ## ###### "); waddstr(wGameOver, " ## ## ## ####### ## "); waddstr(wGameOver, " ## ### ###### ## # ## ##### "); waddstr(wGameOver, " ## ## ## ## ## ## ## "); waddstr(wGameOver, " ##### ## ## ## ## ###### "); waddstr(wGameOver, " "); waddstr(wGameOver, " #### ## ## ###### ###### "); waddstr(wGameOver, " ## ## ## ## ## ## ## "); waddstr(wGameOver, " ## ## ## ## ##### ###### "); waddstr(wGameOver, " ## ## ## ## ## ## ## "); waddstr(wGameOver, " #### ### ###### ## ## "); waddstr(wGameOver, " "); } /** * display game over graphic */ void gameOverDisplay() { int x = (SCREENWIDTH / 2) - (31 / 2); int y = (SCREENHEIGHT / 2) - (13 / 2); copywin(wGameOver, wBattleField, 0, 0, y, x, y + 12, x + 30, 0); wrefresh(wBattleField); } /** * initialize title screen */ static void titleScreenInit() { wTitleScreen = newpad(SCREENHEIGHT, SCREENWIDTH); wclear(wTitleScreen); } /** * display title screen */ void titleScreenDisplay() { static int frame = 0; int x, y; int i; WINDOW *wTitleText; WINDOW *wAliens; WINDOW *wStartText; char ufo[4][6] = {"", "", "", "< oo>"}; char aliens[2][9][3+1] = { {",^,", "_O-", "-o-", "o=o", "", "_x_", "*^*", "\\_/", "o o"}, {".-.", "-O_", "/o\\", "o-o", "", "-x-", "o^o", "/~\\", "oo "} }; int score[3] = {200, 150, 100}; int colors[9] = {RED, GREEN, BLUE, RED, GREEN, BLUE, RED, GREEN, BLUE}; char buffer[12]; static int alien_type = 0; wTitleText = newpad(4, 41); wclear(wTitleText); wattrset(wTitleText, COLOR_PAIR(YELLOW)); waddstr(wTitleText, " ____ __ "); waddstr(wTitleText, " ___ / _/__ _ _____ ___/ /__ _______"); waddstr(wTitleText, " / _ \\_/ // _ \\ |/ / _ `/ _ / -_) __(_-<"); waddstr(wTitleText, "/_//_/___/_//_/___/\\_,_/\\_,_/\\__/_/ /___/"); frame++; wAliens = newpad(7, 11); wclear(wAliens); snprintf(buffer, sizeof(buffer),"%s = 500", ufo[frame % 4]); wattrset(wAliens, COLOR_PAIR(MAGENTA)); waddstr(wAliens, buffer); if ((frame = frame % 60) == 0) { alien_type = 0; } else if (frame == 20) { alien_type = 3; } else if (frame == 40) { alien_type = 6; } for (i = alien_type; i < alien_type + 3; i++) { waddstr(wAliens, " "); snprintf(buffer, sizeof(buffer), "%s = %d", aliens[frame % 2][i], score[i % 3]); wattrset(wAliens, COLOR_PAIR(colors[i])); waddstr(wAliens, buffer); } wStartText = newpad(1, 20); wclear(wStartText); wattrset(wStartText, COLOR_PAIR(RED)); waddstr(wStartText, "Press SPACE to start"); x = (SCREENWIDTH / 2) - (41 / 2); y = 0; copywin(wTitleText, wTitleScreen, 0, 0, y, x, y + 3, x + 40, 0); x = (SCREENWIDTH / 2) - (11 / 2); y = 8; copywin(wAliens, wTitleScreen, 0, 0, y, x , y + 6, x + 10, 0); x = (SCREENWIDTH / 2) - (20 / 2); y = SCREENHEIGHT - 2; copywin(wStartText, wTitleScreen, 0, 0, y, x, y, x + 19, 0); copywin(wTitleScreen, wBattleField, 0, 0, 0, 0, SCREENHEIGHT-1, SCREENWIDTH-1, 0); wrefresh(wBattleField); } /** * clear title screen */ void titleScreenClear() { battleFieldClear(); } /** * initialize scores */ void statusInit() { wStatus = newpad(1, 55); wclear(wStatus); } /** * display scores */ void statusDisplay(int level, int score, int lives) { int t, xOffset; char strStatus[55]; // "Level: 01 Score: 0001450 Lives: /-\ /-\ /-\ /-\ /-\ " // "1234567890123456789012345678901234567890123456789012" xOffset = (SCREENWIDTH / 2) - 24; sprintf (strStatus, "Level: %2.2d Score: %2.7d Lives: ", level, score); wclear(wStatus); wattrset(wStatus, COLOR_PAIR(RED)); waddstr(wStatus, strStatus); // show maximal five lives for (t = 1; ((t <= 5) && (t < lives)); t++){ waddstr(wStatus, "/-\\ "); } copywin(wStatus, wBattleField, 0, 0, SCREENHEIGHT-1, xOffset, SCREENHEIGHT-1, xOffset + 54, 0); } /** * initialize battlefield */ static void battleFieldInit() { wEmpty = newpad(SCREENHEIGHT, SCREENWIDTH); wclear(wEmpty); wBattleField = newwin(SCREENHEIGHT, SCREENWIDTH, 0, 0); // new window wclear(wBattleField); // clear window mvwin(wBattleField, 0, 0); // move window } /** * clear battlefield */ void battleFieldClear() { copywin(wEmpty,wBattleField,0,0,0,0,SCREENHEIGHT-1,SCREENWIDTH-1,0); } /** * refresh screen so that modified graphic buffers get visible */ void refreshScreen() { redrawwin(wBattleField); // needed to display graphics properly at startup on some terminals wrefresh(wBattleField); } /** * do proper cleanup */ static void finish(int sig) { endwin(); // reset terminal into proper non-visual mode exit(0); } /** * initialize n_courses */ void graphicEngineInit() { (void) signal(SIGINT, finish); // on signal "SIGINT" call method "finish" (void) initscr(); // do initialization work keypad(stdscr, TRUE); // enable keypad for input (void) nonl(); // disable translation return/ newline for detection of return key (void) cbreak(); // do not buffer typed characters, use at once (void) noecho(); // do not echo typed characters start_color(); // use colors init_pair(RED, COLOR_RED, COLOR_BLACK); // define color-pair init_pair(GREEN, COLOR_GREEN, COLOR_BLACK); // define color-pair init_pair(YELLOW, COLOR_YELLOW, COLOR_BLACK); // define color-pair init_pair(BLUE, COLOR_BLUE, COLOR_BLACK); // define color-pair init_pair(CYAN, COLOR_CYAN, COLOR_BLACK); // define color-pair init_pair(MAGENTA, COLOR_MAGENTA, COLOR_BLACK); // define color-pair init_pair(WHITE, COLOR_WHITE, COLOR_BLACK); // define color-pair //timeout(0); // do not wait for input // initialize sprites battleFieldInit(); playerInit(); playerMissileInit(); aliensInit(); aliensMissileInit(); bunkersInit(); ufoInit(); gameOverInit(); statusInit(); titleScreenInit(); }