Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

game.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <time.h>
00003 
00004 #include <SDL/SDL.h>
00005 #include <SDL/SDL_image.h>
00006 
00007 #include "font.h"
00008 
00009 #include "constants.h"
00010 #include "game.h"
00011 #include "player.h"
00012 #include "random.h"
00013 #include "sound.h"
00014 #include "stringtokenizer.h"
00015 
00016 #include "sfcave_game.h"
00017 #include "gates_game.h"
00018 #include "fly_game.h"
00019 #include "starfield.h"
00020 
00021 Game :: Game( SFCave *p, int w, int h, int diff )
00022 {
00023         parent = p;
00024         sHeight = h;
00025         sWidth = w;
00026         difficulty = diff;
00027         replayIt = 0;
00028         replay = false;
00029         terrain = 0;
00030         player = 0;
00031         thrustChannel = -1;
00032 }
00033 
00034 Game :: ~Game()
00035 {
00036         if ( terrain )
00037                 delete terrain;
00038 
00039         if ( player )
00040                 delete player;
00041 
00042         replayList.clear();
00043 }
00044 
00045 void Game :: init()
00046 {
00047         if ( replay )
00048         {
00049                 setSeed( currentSeed );
00050                 replayIt = replayList.begin();
00051         }
00052         else
00053         {
00054                 setSeed( -1 );
00055                 replayList.clear();
00056         }
00057         
00058         score = 0;
00059         nrFrames = 0;
00060         press = false;
00061 
00062         // Load highscore
00063         string key = getGameName() + "_" + getGameDifficultyText() + "_highscore";
00064         highScore = atoi( parent->loadSetting( key, "0" ).c_str() );
00065 
00066         terrain->initTerrain();
00067         player->init();
00068 }
00069 
00070 void Game :: handleKeys( SDL_KeyboardEvent &key )
00071 {
00072         if ( !replay && 
00073              (key.keysym.sym == SDLK_SPACE ||
00074              key.keysym.sym == SDLK_KP_ENTER ||
00075              key.keysym.sym == SDLK_RETURN ||
00076              key.keysym.sym == SDLK_UP) )
00077         {
00078                 if ( key.type == SDL_KEYDOWN )
00079                 {
00080                         if ( !press )
00081                                 replayList.push_back( nrFrames );
00082                         press = true;
00083                 }
00084                 else
00085                 {
00086                         if ( press )
00087                                 replayList.push_back( nrFrames );
00088                         press = false;
00089 
00090                 }
00091         }
00092 }
00093 
00094 
00095 
00096 string Game :: getGameDifficultyText()
00097 {
00098         string ret;
00099 
00100         if ( difficulty == MENU_DIFFICULTY_EASY )
00101                 ret =  "Easy";
00102         else if ( difficulty == MENU_DIFFICULTY_NORMAL )
00103                 ret = "Medium";
00104         else if ( difficulty == MENU_DIFFICULTY_HARD )
00105                 ret = "Hard";
00106         else if ( difficulty == MENU_DIFFICULTY_CUSTOM )
00107                 ret = "Custom";
00108 
00109         return ret;
00110 }
00111 
00112 void Game :: setDifficulty( string diff )
00113 {
00114         if ( diff == "Easy" )
00115                 difficulty = MENU_DIFFICULTY_EASY;
00116         else if ( diff == "Medium" )
00117                 difficulty = MENU_DIFFICULTY_NORMAL;
00118         else if ( diff == "Hard" )
00119                 difficulty = MENU_DIFFICULTY_HARD;
00120     else if ( diff == "Custom" )
00121                 difficulty = MENU_DIFFICULTY_CUSTOM;
00122                 
00123     init();
00124 }
00125 
00126 void Game :: setDifficulty( int diff )
00127 {
00128     difficulty = diff;
00129     init();
00130 }
00131 
00132 void Game :: update( int state )
00133 {
00134         nrFrames ++;
00135 
00136         if ( score > highScore )
00137                 highScore = score;
00138 
00139 
00140         if ( state == STATE_PLAYING )
00141         {
00142         if ( replay )
00143         {
00144             while( replayIt != replayList.end() && (*replayIt) == nrFrames-1 )
00145             {
00146                 press = !press;
00147                 replayIt ++;
00148             }
00149         }
00150 
00151                 if ( press && thrustChannel == -1 )
00152                         thrustChannel = SoundHandler :: playSound( SND_THRUST, -1, -1, false );
00153 
00154                 if ( !press &&thrustChannel != -1 )
00155                 {
00156                         SoundHandler :: stopSound( thrustChannel, true, 300 );
00157                         thrustChannel = -1;
00158                 }
00159         }
00160 
00161         if ( state == STATE_CRASHING || state == STATE_CRASHED )
00162         {
00163                 // fade out any trail marks remainin
00164                 if ( player->updateCrashing() )
00165                         parent->changeState( STATE_CRASHED );
00166 
00167         }
00168 }
00169 
00170 void Game :: preDraw( SDL_Surface *screen )
00171 {
00172 }
00173 
00174 void Game :: draw( SDL_Surface *screen )
00175 {
00176         char tmp[100];
00177         string scoreText;
00178         sprintf( tmp, "Score: %06ld   High Score: %06ld", score, highScore );
00179         FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 3, 10 );
00180 
00181         if ( parent->getState() == STATE_CRASHED )
00182         {
00183                 string crashText;
00184                 crashText = "Game Over";
00185                 int x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2;
00186                 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 );
00187 
00188                 int fontHeight = FontHandler::FontHeight( FONT_WHITE_TEXT );
00189                 crashText = "Press Middle Button to play again";
00190                 x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2;
00191                 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + fontHeight );
00192 
00193                 crashText = "or OK for menu";
00194                 x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2;
00195                 FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + 2*fontHeight );
00196         }
00197 
00198         if ( parent->showFPS() )
00199         {
00200                 sprintf( tmp, "FPS : %d", parent->getFPS() );
00201                 FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 20, 300 );
00202         }
00203 }
00204 
00205 void Game :: stateChanged( int from, int to )
00206 {
00207         if ( from != STATE_CRASHING && to == STATE_CRASHING )
00208         {
00209                 // play explosion sound
00210                 SoundHandler :: stopSound( -1, false );
00211                 SoundHandler :: playSound( SND_EXPLOSION );
00212 
00213                 // Check and save highscore
00214                 printf( "Got Highscore = %d\n", gotHighScore() );
00215                 if ( gotHighScore() )
00216                 {
00217                         string key = getGameName() + "_" +  getGameDifficultyText() + "_highscore";
00218                         parent->saveSetting( key, getHighScore() );
00219                 }
00220 
00221         }
00222 }
00223 
00224 void Game :: setSeed( int seed )
00225 {
00226     if ( seed == -1 )
00227         currentSeed = ((unsigned long) time((time_t *) NULL));
00228     else
00229         currentSeed = seed;
00230     PutSeed( currentSeed );
00231 }
00232 
00233 void Game :: saveReplay( string file )
00234 {
00235     FILE *out;
00236     out = fopen( file.c_str(), "w" );
00237     if ( !out )
00238     {
00239         printf( "Couldn't write to /home/root/%s\n", file.c_str() );
00240                 parent->setMenuStatusText( "Couldn't save replay file" );
00241         return;
00242     }
00243 
00244     // Build up string of values
00245     // Format is:: <landscape seed> <game type> <difficulty> <framenr> <framenr>.......
00246     string val;
00247     char tmp[20];
00248     sprintf( tmp, "%d %d ", currentSeed, difficulty );
00249     val = tmp;
00250 
00251     list<int>::iterator it = replayList.begin();
00252     while( it != replayList.end() )
00253     {
00254         sprintf( tmp, "%d ", *it );
00255         val += tmp;
00256 
00257         it++;
00258     }
00259     val += "\n";
00260 
00261     string line;
00262     sprintf( tmp, "%d\n", val.length() );
00263     line = tmp;
00264     fwrite( line.c_str(), 1, line.length(), out );
00265 
00266     fwrite( val.c_str(), 1, val.length(), out );
00267 
00268     fclose( out );
00269 }
00270 
00271 void Game :: loadReplay( string file )
00272 {
00273 
00274     FILE *in = fopen( (const char *)file.c_str(), "r" );
00275 
00276     if ( in == 0 )
00277     {
00278         printf( "Couldn't load replay file %s!\n", (const char *)file.c_str() );
00279                 parent->setMenuStatusText( "Couldn't load replay file" );
00280         return;
00281     }
00282 
00283     // Read next line - contains the size of the options
00284     char line[10+1];
00285     fgets( line, 10, in );
00286 
00287     int length = -1;
00288     sscanf( line, "%d", &length );
00289     char *data = new char[length+1];
00290 
00291     fread( data, 1, length, in );
00292 
00293     string sep  = " ";
00294 
00295     StringTokenizer st( data, sep );
00296 
00297     // print it out
00298     vector<string>::iterator it = st.begin();
00299     currentSeed = atoi( (*it).c_str() );
00300     ++it;
00301     difficulty = atoi( (*it).c_str() );
00302     ++it;
00303 
00304     replayList.clear();
00305     for ( ; it != st.end(); ++it )
00306     {
00307         int v = atoi( (*it).c_str() );
00308         replayList.push_back( v );
00309     }
00310 
00311     delete data;
00312 
00313     fclose( in );
00314 }
00315 
00316 
00317 Game *Game :: createGame( SFCave *p, int w, int h, string game, string difficulty )
00318 {
00319         Game *g;
00320 
00321         if ( game == "SFCave" )
00322                 g = new SFCaveGame( p, w, h, 0 );
00323         else if ( game == "Gates" )
00324                 g = new GatesGame( p, w, h, 0 );
00325         else if ( game == "Fly" )
00326                 g = new FlyGame( p, w, h, 0 );
00327 
00328         if ( g )
00329                 g->setDifficulty( difficulty );
00330 
00331         return g;
00332 }

Generated on Sat Nov 5 16:17:18 2005 for OPIE by  doxygen 1.4.2