Files
commandergenius/project/jni/application/alienblaster/game.cpp

964 lines
25 KiB
C++

/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sstream>
#include <android/log.h>
#include "SDL.h"
#include "mixer.h"
#include "game.h"
#include "surfaceDB.h"
#include "racers.h"
#include "racer.h"
#include "video.h"
#include "shots.h"
#include "shot.h"
#include "items.h"
#include "explosions.h"
#include "explosion.h"
#include "enemys.h"
#include "font.h"
#include "mixer.h"
#include "input.h"
#include "wrecks.h"
#include "wreck.h"
#include "global.h"
#include "settings.h"
#include "intro.h"
#include "setDifficulty.h"
#include "menuArcadeMode.h"
#include "asstring.h"
#include "sonic.h"
#include "banners.h"
#include "banner.h"
#include "smokePuffs.h"
#include "background.h"
#include "options.h"
Racers *racers = NULL;
Enemys *enemys = NULL;
Shots *shots = NULL;
Explosions *explosions = NULL;
Items *items = NULL;
Wrecks *wrecks = NULL;
Banners *banners = NULL;
SmokePuffs *smokePuffs = NULL;
Options *levelConf = NULL;
bool scrollingOn;
bool nukeIsInPlace;
bool playMusicOn;
bool onePlayerGame;
bool arcadeGame;
int difficultyLevel;
float actBackgroundPos;
Game::Game() {
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 1");
videoserver = new Video();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 2");
screen = 0;
screen = videoserver->init();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 3");
settings = new Settings();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 4");
intro = new Intro( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 5");
setDifficulty = new SetDifficulty( screen );
menuArcadeMode = new MenuArcadeMode( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 6");
pauseSprite = surfaceDB.loadSurface( FN_PAUSED );
youLoseSprite = surfaceDB.loadSurface( FN_YOU_LOSE );
youWinSprite = surfaceDB.loadSurface( FN_YOU_WIN );
// for arcadeMode
gameOverSprite = surfaceDB.loadSurface( FN_GAME_OVER );
nukeEffectSurface = surfaceDB.loadSurface( FN_NUKE_EFFECT );
bossAlarm = Mixer::mixer().loadSample( FN_SOUND_BOSS_ALARM, 60 );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 7");
fontTime = new Font( FN_FONT_NUMBERS_TIME );
fontSizeTime = fontTime->getCharWidth();
racers = 0;
explosions = 0;
enemys = 0;
shots = 0;
items = 0;
wrecks = 0;
banners = 0;
smokePuffs = 0;
// needed for calculating fps
frameCnt = 0;
tickCnt = 0;
gameState = GS_INTRO;
paused = true;
sdlTicks = SDL_GetTicks();
gameActRuntime = 0;
timeNukeEnd = 0;
timePauseOn = 0;
timeMinibossOn = 0;
scrollingOn = true;
showAllShipStats = false;
playMusicOn = true;
onePlayerGame = false;
arcadeGame = false;
difficultyLevel = 1;
sonic1 = new Sonic();
sonic2 = new Sonic();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 8");
background = new Background();
loadLevel( FN_LEVEL_ONE_PLAYER );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 9");
SdlCompat_AcceleratedSurface *loadingSprite = surfaceDB.loadSurface( FN_LOADING );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 10");
SDL_Rect dest;
dest.x = (SCREEN_WIDTH - loadingSprite->w ) / 2;
dest.y = (SCREEN_HEIGHT - loadingSprite->h ) / 2;
dest.w = loadingSprite->w;
dest.h = loadingSprite->h;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 11");
SDL_BlitSurface( loadingSprite, 0, screen, &dest );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 12");
SDL_Flip( screen );
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 13");
initAllSurfaces();
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", "Game() 14");
}
Game::~Game(){
if (videoserver) delete videoserver;
if (settings) delete settings;
if (intro) delete intro;
if (setDifficulty) delete setDifficulty;
if (racers) delete racers;
if (shots) delete shots;
if (explosions) delete explosions;
if (enemys) delete enemys;
if (items) delete items;
if (wrecks) delete wrecks;
if (fontTime) delete fontTime;
if (sonic1) delete sonic1;
if (sonic2) delete sonic2;
if (banners) delete banners;
if (smokePuffs) delete smokePuffs;
}
void Game::initNewGame() {
parseGlobalConfigValues( difficultyLevel );
if (racers) delete racers;
if (shots) delete shots;
if (explosions) delete explosions;
if (enemys) delete enemys;
if (items) delete items;
if (wrecks) delete wrecks;
if (sonic1) delete sonic1;
if (sonic2) delete sonic2;
if (banners) delete banners;
if (smokePuffs) delete smokePuffs;
banners = new Banners();
smokePuffs = new SmokePuffs();
racers = new Racers();
Racer *racer;
if ( !arcadeGame ) {
if ( onePlayerGame ) {
loadLevel( FN_LEVEL_ONE_PLAYER );
if ( setDifficulty->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(320,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(320,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
// two players
else {
loadLevel( FN_LEVEL_TWO_PLAYER );
if ( setDifficulty->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(250,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(250,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
if ( setDifficulty->getPlayerTwoLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_2, 1,
Vector2D(390,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_2, 1,
Vector2D(390,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
}
// arcade game
else {
loadLevel( FN_LEVEL_ARCADEMODE );
if ( menuArcadeMode->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(320,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(320,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
racers->getKeyActionMaps();
explosions = new Explosions();
enemys = new Enemys();
shots = new Shots();
items = new Items();
wrecks = new Wrecks();
gameActRuntime = 0;
paused = true;
bossTime = false;
bossNukeEffect = false;
bossExplosion = Mixer::mixer().loadSample( FN_SOUND_EXPLOSION_BOSS );
minibossAlreadyKilled = false;
minibossTime = false;
timeMinibossOn = SDL_GetTicks();
timeLastUpdate = SDL_GetTicks();
timeNukeEnd = SDL_GetTicks();
timePauseOn = SDL_GetTicks();
actBackgroundPos = 0;
scrollingOn = true;
nukeIsInPlace = false;
sonic1 = new Sonic();
sonic2 = new Sonic();
sonic1->setActive( false );
sonic2->setActive( false );
}
void Game::run(){
while( gameState != GS_QUIT ) {
switch (gameState) {
case GS_SCREENSHOTS:
{
intro->showScreenshots();
gameState = GS_INTRO;
break;
}
case GS_INTRO:
{
intro->run( gameState );
break;
}
case GS_SET_DIFFICULTY:
{
setDifficulty->run( gameState, onePlayerGame);
break;
}
case GS_ARCADE_MODE_SETUP:
{
menuArcadeMode->run( gameState );
break;
}
case GS_ARCADE_MODE_FINISHED:
{
menuArcadeMode->run( gameState, racers->getPointsArcadeMode() );
break;
}
case GS_OPTIONS:
{
options();
break;
}
case GS_ROUNDFINISHED:
{
roundFinished();
break;
}
case GS_BOSS_KILLED:
{
bossKilled();
break;
}
case GS_PLAYON:
{
initNewGame();
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 1000 );
playOn();
break;
}
default: break;
}
}
}
/*********************************/
/**** PlayOn *********************/
/*********************************/
void Game::playOn() {
int A = SDL_GetTicks();
frameCnt = 0;
tickCnt = 0;
{
std::ostringstream logout;
logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
<< " SDL_GetTicks()=" << A;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str());
}
while ( gameState == GS_PLAYON ) {
handleEventsPlayOn();
if (!paused) {
updateGameState();
}
drawPlayOn();
// miniboss
if ( minibossTime && enemys->minibossDead() ) minibossAlreadyKilled = true;
if (!minibossAlreadyKilled && !arcadeGame && !paused && !minibossTime &&
(unsigned int)GAME_LENGTH / 2 <= gameActRuntime) {
generateMiniboss();
}
if ( minibossTime && enemys->bossDead() ) minibossKilled();
// endboss
if (!arcadeGame && !paused && !bossTime && !minibossTime &&
(unsigned int)GAME_LENGTH < gameActRuntime) {
enemys->bossTime(1); // generates the boss
bossTime = true;
Mixer::mixer().playSample( bossAlarm , 0, true );
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 0 );
}
if ( bossTime && enemys->bossDead() ) gameState = GS_BOSS_KILLED;
if ( racers->bothPlayersLost() ) gameState = GS_ROUNDFINISHED;
}
{
std::ostringstream logout;
int B = SDL_GetTicks();
logout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
<< " SDL_GetTicks()=" << B << endl;
logout << "Milliseconds: " << B-A << endl;
logout << "Frames/sec : " << (float)frameCnt / ((float)(B-A) / 1000.0) << endl;
logout << "ms/Frame : " << (float)tickCnt / (float)frameCnt << endl;
__android_log_print(ANDROID_LOG_INFO, "Alien Blaster", logout.str().c_str());
}
}
void Game::pause() {
if (paused) {
Uint32 timePaused = SDL_GetTicks() - timePauseOn;
timeLastUpdate += timePaused;
} else {
timePauseOn = SDL_GetTicks();
}
paused = !paused;
}
void Game::handleEventsPlayOn() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_JOYBUTTONDOWN:
case SDL_KEYDOWN:
case SDL_MOUSEBUTTONDOWN: {
if (paused) pause();
racers->handleEvent(input.translate(event), input.isPressed(event));
break;
}
case SDL_KEYUP: {
switch(event.key.keysym.sym) {
case SDLK_F10: {
pause();
break;
}
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F6: {
showAllShipStats = !showAllShipStats;
break;
}
case SDLK_ESCAPE: {
gameState = GS_INTRO;
break;
}
case SDLK_F1: {
if (!paused) pause();
settings->settingsDialog(screen);
racers->getKeyActionMaps();
pause();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
Mixer::mixer().stopMusic();
} else {
playMusicOn = true;
if ( bossTime ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 1000 );
else Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 1000 );
}
break;
}
default: break;
}
}
case SDL_JOYAXISMOTION:
case SDL_JOYBUTTONUP:
case SDL_MOUSEBUTTONUP:
racers->handleEvent(input.translate(event), input.isPressed(event));
break;
case SDL_QUIT: {
gameState = GS_QUIT;
break;
}
default: break;
}
}
}
// what to do in one tick
void Game::updateGameState() {
int dT = SDL_GetTicks() - timeLastUpdate;
timeLastUpdate += dT;
if ( !minibossTime ) gameActRuntime += dT;
if ( nukeIsInPlace ) handleNuke();
enemys->generateEnemys( dT );
explosions->updateExplosions( dT );
smokePuffs->update( dT );
shots->moveAndCollide( dT );
wrecks->updateWrecks( dT );
enemys->updateEnemys( dT );
if ( !arcadeGame ) items->generate( dT );
items->update( dT );
racers->moveAndCollide( dT );
racers->pickUpItems();
racers->shoot();
if ( !arcadeGame ) racers->rechargeShield( dT );
enemys->deleteExpiredEnemys();
shots->expireShots();
items->expireItems();
explosions->expireExplosions();
wrecks->expireWrecks();
racers->expireRacers();
smokePuffs->expireSmokePuffs();
sonicDeflectorEffect();
banners->update( dT );
banners->expireBanners();
if ( scrollingOn ) actBackgroundPos -= SCROLL_SPEED * dT / 1000.0;
if ( arcadeGame ) {
racers->receivePointsArcade( ARCADE_POINTS_PER_TEN_SECONDS * dT / 10000.0 );
}
}
void Game::handleNuke() {
sonic1->setActive( false );
sonic2->setActive( false );
enemys->doNukeDamage();
shots->deleteAllShots();
timeNukeEnd = SDL_GetTicks() + NUKE_EFFECT_DURATION;
nukeIsInPlace = false;
}
void Game::sonicDeflectorEffect() {
for ( unsigned int i = 0; i < racers->getNrRacers(); i++) {
if ( racers->getRacer(i)->getShipType() == LIGHT_FIGHTER ) {
Shot* nearestRocket = shots->getNearestRocket( racers->getRacer(i)->getPos() );
// a rocket exists and it is in range of the sonic
if ( nearestRocket != NULL &&
(nearestRocket->getPos() - racers->getRacer(i)->getPos()).getLength() <
RACER_SONIC_ACTIVATION_DIST ) {
// activate the correct sonic
if (i == 0) {
sonic1->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
nearestRocket->deflectedBySonicFromPlayer1 = true;
} else {
sonic2->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
nearestRocket->deflectedBySonicFromPlayer2 = true;
}
// no rocket is in sonic-range
} else {
// deactivate the sonic
if (i == 0) {
sonic1->setActive( false );
} else {
sonic2->setActive( false );
}
}
}
}
}
void Game::drawPlayOn() {
drawBackground();
wrecks->draw(screen);
enemys->drawGroundEnemys(screen);
shots->drawShadows(screen);
racers->drawShadows(screen);
enemys->drawShadows(screen);
explosions->drawGroundExplosions(screen);
smokePuffs->draw(screen);
sonic1->draw(screen);
sonic2->draw(screen);
shots->drawGroundShots(screen);
shots->drawGroundAirShots(screen);
items->draw(screen);
enemys->drawAirEnemys(screen);
racers->drawRacers(screen);
shots->drawAirShots(screen);
explosions->drawAirExplosions(screen);
if ( showAllShipStats ) enemys->drawAllStats(screen);
else {
if ( bossTime ) {
enemys->drawBossStats(screen);
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
}
}
if ( SDL_GetTicks() < timeNukeEnd ) {
drawNukeEffect();
}
racers->drawStats(screen);
banners->draw(screen);
if ( !arcadeGame && !bossTime && !minibossTime ) drawTime();
else {
if ( bossTime || minibossTime ) {
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
}
else {
drawPointsArcadeMode();
}
}
if (paused) drawPaused();
SDL_Flip( screen );
frameCnt++;
}
void Game::drawBackground() {
background->draw(screen, (int) (actBackgroundPos + 0.5) );
}
void Game::drawTime() {
Uint32 timeToDraw;
timeToDraw = (GAME_LENGTH - gameActRuntime) / 1000;
if ( timeToDraw > 0 ) {
int digitCnt = 1;
Uint32 i=1;
while ( timeToDraw >= i*10 ) {
digitCnt++;
i *= 10;
}
fontTime->drawInt(screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 5,
timeToDraw, digitCnt, 0);
}
}
void Game::drawPointsArcadeMode() {
int pointsToDraw = racers->getPointsArcadeMode();
if ( pointsToDraw < 0 ) return;
int digitCnt = 1;
int i=1;
while ( pointsToDraw >= i*10 ) {
digitCnt++;
i *= 10;
}
fontTime->drawInt( screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 10,
pointsToDraw, digitCnt, 0);
}
void Game::drawPaused() {
SDL_Rect r;
r.x = screen->w/2 - pauseSprite->w/2;
r.y = screen->h/2 - pauseSprite->h/2;
r.w = pauseSprite->w;
r.h = pauseSprite->h;
SDL_BlitSurface( pauseSprite, 0, screen, &r );
}
void Game::drawNukeEffect() {
// effect-process: transparent -> nearly opaque -> transparent
int timeFromMaximum = (NUKE_EFFECT_DURATION / 2) - (timeNukeEnd - SDL_GetTicks());
timeFromMaximum = abs(timeFromMaximum);
SDL_SetAlpha( nukeEffectSurface, SDL_SRCALPHA,
lroundf(((NUKE_EFFECT_DURATION / 2) - timeFromMaximum) * 128.0 /
(NUKE_EFFECT_DURATION / 2)) );
SDL_BlitSurface( nukeEffectSurface, 0, screen, 0 );
/*
int randRange = (int)
(( ((NUKE_EFFECT_DURATION / 2.0) - timeFromMaximum) * NUKE_QUAKE_EFFECT /
(NUKE_EFFECT_DURATION / 2.0 ) ) + 0.5);
int randX, randY;
if ( randRange == 0 ) randRange = 1;
randX = (rand() % randRange) - randRange / 2;
randY = (rand() % randRange) - randRange / 2;
SDL_Rect src, dest;
if ( randX < 0 ) {
src.x = -randX;
src.w = screen->w + randX;
dest.x = 0;
dest.w = screen->w + randX;
} else {
src.x = 0;
src.w = screen->w - randX;
dest.x = randX;
dest.w = screen->w - randX;
}
if ( randY < 0 ) {
src.y = -randY;
src.h = screen->h + randY;
dest.y = 0;
dest.h = screen->h + randY;
} else {
src.y = 0;
src.h = screen->h - randY;
dest.y = randY;
dest.h = screen->h - randY;
}
SDL_BlitSurface( screen, &src, screen, &dest );
*/
}
// not in use - not needed anymore
void Game::timeManagement() {
Uint32 sdlTicksNew = SDL_GetTicks();
tickCnt += sdlTicksNew - sdlTicks;
// 25 Frames per Second is wanted
// we needed less than 40 ms -> wait till the 40 ms are over
while ( sdlTicks + 40 > sdlTicksNew ) {
sdlTicksNew = SDL_GetTicks();
}
sdlTicks = sdlTicksNew;
}
/***********************************/
/** Options ************************/
/***********************************/
void Game::options() {}
/************************************/
/** Round Finished ******************/
/************************************/
void Game::roundFinished() {
drawRoundFinished();
SDL_Flip( screen );
while (gameState == GS_ROUNDFINISHED ) {
handleEventsRoundFinished();
}
}
void Game::handleEventsRoundFinished() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYUP:
{
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_SPACE:
case SDLK_RETURN:
{
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
else gameState = GS_INTRO;
break;
}
case SDLK_F5:
{
videoserver->toggleFullscreen();
break;
}
default:
{
break;
}
}
break;
}
case SDL_QUIT:
{
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
else gameState = GS_INTRO;
break;
}
default: break;
}
}
}
void Game::drawRoundFinished() {
SDL_Rect r;
if ( arcadeGame ) {
r.x = screen->w/2 - gameOverSprite->w / 2;
r.y = screen->h/2 - gameOverSprite->h / 2;
r.w = gameOverSprite->w;
r.h = gameOverSprite->h;
SDL_BlitSurface( gameOverSprite, 0, screen, &r );
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 50,
"SCORE: " + asString( racers->getPointsArcadeMode() ),
FONT_ALIGN_CENTERED );
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 100,
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
+ "/" + asString(enemys->getNrEnemysGenerated()),
FONT_ALIGN_CENTERED );
}
// normal game
else {
if ( racers->bothPlayersLost() ) {
r.x = screen->w/2 - youLoseSprite->w / 2;
r.y = screen->h/2 - youLoseSprite->h / 2;
r.w = youLoseSprite->w;
r.h = youLoseSprite->h;
SDL_BlitSurface( youLoseSprite, 0, screen, &r );
} else {
r.x = screen->w/2 - youWinSprite->w / 2;
r.y = screen->h/2 - youWinSprite->h / 2;
r.w = youWinSprite->w;
r.h = youWinSprite->h;
SDL_BlitSurface( youWinSprite, 0, screen, &r );
fontTime->drawStr(screen, screen->w/2, screen->h/2 + youWinSprite->h/2 + 50,
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
+ ":" + asString(enemys->getNrEnemysGenerated()),
FONT_ALIGN_CENTERED);
}
}
}
/************************************/
/** Miniboss ***********************/
/************************************/
void Game::generateMiniboss() {
scrollingOn = false;
minibossTime = true;
enemys->bossTime(2); // generates the miniboss
Mixer::mixer().playSample( bossAlarm , 0, true );
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_BOSS1, -1, 0 );
}
void Game::minibossKilled() {
scrollingOn = true;
minibossTime = false;
if ( playMusicOn ) Mixer::mixer().playMusic( MUSIC_PLAYON, -1, 0 );
}
/************************************/
/** Boss Killed *********************/
/************************************/
void Game::bossKilled() {
int BOSS_EXPLOSION_DURATION = 3000;
int startOfBossExplosion = SDL_GetTicks();
int actualTime;
bool bossExplosionSound = false;
timeNukeEnd = SDL_GetTicks() + BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION;
while ( gameState == GS_BOSS_KILLED ) {
actualTime = SDL_GetTicks();
updateBossKilled();
if ( (actualTime - startOfBossExplosion) < BOSS_EXPLOSION_DURATION ) {
// explosions
Explosion *newExplosion =
new Explosion( FN_EXPLOSION_ENEMY,
Vector2D( rand() % SCREEN_WIDTH, rand() % 150 ),
Vector2D( 0, 0 ),
EXPLOSION_NORMAL_GROUND );
explosions->addExplosion( newExplosion );
}
else if ( (actualTime - startOfBossExplosion) < (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION) ) {
// nuke effect
if ( !bossExplosionSound ) {
Mixer::mixer().playSample( bossExplosion, 0, true );
bossExplosionSound = false;
enemys->doNukeDamage();
enemys->deleteExpiredEnemys();
shots->deleteAllShots();
items->deleteAllItems();
wrecks->deleteAllWrecks();
Wreck *newWreck = new Wreck( Vector2D( SCREEN_WIDTH / 2, 70 ), WRECK_BOSS_1_DESTROYED);
wrecks->addWreck( newWreck );
bossNukeEffect = true;
}
}
else {
bossNukeEffect = false;
}
if ( (actualTime - startOfBossExplosion) > (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION + 4000) ) {
gameState = GS_ROUNDFINISHED;
}
drawBossKilled();
handleEventsBossKilled();
}
}
void Game::handleEventsBossKilled() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYUP: {
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_SPACE:
case SDLK_RETURN:
{
gameState = GS_INTRO;
break;
}
case SDLK_F5:
{
videoserver->toggleFullscreen();
break;
}
default: break;
}
break;
}
case SDL_QUIT:
{
gameState = GS_INTRO;
break;
}
default: break;
}
}
}
void Game::drawBossKilled() {
drawBackground();
wrecks->draw(screen);
enemys->drawGroundEnemys(screen);
shots->drawShadows(screen);
racers->drawShadows(screen);
enemys->drawShadows(screen);
explosions->drawGroundExplosions(screen);
shots->drawGroundShots(screen);
shots->drawGroundAirShots(screen);
items->draw(screen);
enemys->drawAirEnemys(screen);
racers->drawRacers(screen);
shots->drawAirShots(screen);
explosions->drawAirExplosions(screen);
if ( bossNukeEffect ) drawNukeEffect();
racers->drawStats(screen);
SDL_Flip( screen );
}
void Game::updateBossKilled() {
int dT = SDL_GetTicks() - timeLastUpdate;
timeLastUpdate += dT;
explosions->updateExplosions( dT );
explosions->expireExplosions();
}
void Game::loadLevel( string fn ) {
if (levelConf) {
delete levelConf;
}
levelConf = new Options( fn );
// load background tiles
background->clearTileList();
int cnt = 0;
if (!levelConf->getInt( LVL_BACKG_TILE_CNT, cnt )) {
cout << "ERROR: " << fn << " contains no '" << LVL_BACKG_TILE_CNT << "' keyword!" << endl;
exit(0);
}
for(int i=0; i < cnt; i++) {
string tilename;
if (levelConf->getStr( LVL_BACKG_TILE + asString( i ), tilename ) ) {
background->addTile( tilename );
}
}
int len = SCREEN_WIDTH;
levelConf->getInt( LVL_BACKG_LENGTH, len );
background->generateBackground( len );
}