C:/Documents and Settings/mtauraso/Desktop/proj3/projectX/Level.cpp

Go to the documentation of this file.
00001 #include "Level.h"
00002 #include "Screen.h"
00003 #include "CommandManager.h"
00004 #include "Object.h"
00005 #include "Player.h"
00006 #include "Control.h"
00007 #include "Camera.h"
00008 #include "Parser.h"
00009 
00010 #include <io.h>
00011 #include <iostream>
00012 #include <sstream>
00013 #include <cassert>
00014 
00015 using namespace std;
00016 
00017 Uint32 Level::WALKBEHIND = 0;
00018 Uint32 Level::WALKINTO = 0;
00019 Uint32 Level::WALKINFRONT = 0;
00020 bool Level::_objectsLoaded = false;
00021 map<Uint32,Sprite *> Level::TEXTURES;
00022 map<Uint32,string> Level::OBJECTS;
00023 Level *Level::_instance = NULL;
00024 
00025 Level::Level()
00026 :_cutScene(false),_score(0)
00027 {
00028         loadObjects();
00029         
00030 
00031         _instance = this;
00032 }
00033 
00034 
00035 Level::~Level()
00036 {
00037         for(int i=0; i<_objects.size(); i++)
00038                 delete _objects[i];
00039         for(int i=0; i<_tiles.size(); i++)
00040                 delete _tiles[i];
00041 }
00042 
00043 void Level::reset()
00044 {
00045         for(int i=0; i<_objects.size(); i++)
00046                 delete _objects[i];
00047         for(int i=0; i<_tiles.size(); i++)
00048                 delete _tiles[i];
00049 
00050         _objects.clear();
00051         _tiles.clear();
00052         _drawnObjects.clear();
00053         _deleteQueue.clear();
00054 
00055         _ids.clear();
00056 
00057         while(!_addQueue.empty())
00058         {
00059                 delete _addQueue.front();
00060                 _addQueue.pop();
00061         }
00062 
00063         levelLoad(_filenamebase);
00064 
00065 }
00066 
00067 void Level::loadObjects()
00068 {
00069         if(!_objectsLoaded) {
00070                 readTextures("png");
00071                 readTextures("txt");
00072                 
00073                 WALKBEHIND = loadPixelFile("levels/walkbehind_p.png");
00074                 WALKINFRONT = loadPixelFile("levels/walkinfront_p.png");
00075                 WALKINTO = loadPixelFile("levels/walkinto_p.png");
00076 
00077                 readObjects("characters");
00078                 readObjects("events");
00079                 readObjects("cutscenes");
00080                 readObjects("entities");
00081                 //readTextures("bmp");
00082                 _objectsLoaded = true;
00083         }
00084 }
00085 
00086 Uint32 Level::loadPixelFile(std::string filename)
00087 {
00088         SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00089         SDL_LockSurface(surface);
00090         Uint32 pixel=*((Uint32*)surface->pixels);
00091         SDL_UnlockSurface(surface);
00092         SDL_FreeSurface(surface);
00093         return pixel;
00094 }
00095 
00096 void Level::readObjects(std::string dir)
00097 {
00098         struct _finddata_t file;
00099         intptr_t hFile;
00100         string extension = "txt";
00101 
00102         if( (hFile = _findfirst( (dir + "/*." + extension).c_str(), &file )) != -1L ) {
00103                 do {
00104                         string filename(file.name);
00105                         
00106                         string end = filename.substr(filename.size() - 6,2);
00107                         if(end != "_p") {
00108 
00109                                 filename = dir + "/" + filename;
00110                                 //Sprite * sprite = new Sprite(filename, tileWidth, tileHeight);
00111                                 string objFile = filename;
00112 
00113                                 //filename.insert(filename.find("."),"_p");
00114                                 filename.erase(filename.find("."),4);
00115                                 filename += "_p.png";
00116 
00117                                 SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00118                                 SDL_LockSurface(surface);
00119                                 Uint32 pixel=*((Uint32*)surface->pixels);
00120                                 
00121                                 //cerr << (int) pixel << endl;
00122 
00123                                 SDL_UnlockSurface(surface);
00124                                 SDL_FreeSurface(surface);
00125 
00126                                 OBJECTS[pixel] = objFile;
00127                         }
00128                         else
00129                                 continue;
00130                 }
00131                 while( _findnext( hFile, &file ) == 0 );
00132 
00133                 _findclose( hFile );
00134         }
00135 }
00136 
00137 void Level::readTextures(std::string extension)
00138 {
00139         struct _finddata_t file;
00140         intptr_t hFile;
00141 
00142         if( (hFile = _findfirst( ("textures/*." + extension).c_str(), &file )) != -1L ) {
00143                 do {
00144                         string filename(file.name);
00145                         
00146                         string end = filename.substr(filename.size() - 6,2);
00147                         if(end != "_p") {
00148 
00149                                 filename = "textures/" + filename;
00150                                 //Sprite * sprite = new Sprite(filename, tileWidth, tileHeight);
00151                                 Sprite * sprite = Sprite::loadSprite(filename);
00152 
00153                                 //filename.insert(filename.find("."),"_p");
00154                                 filename.erase(filename.find("."),4);
00155                                 filename += "_p.png";
00156 
00157                                 SDL_Surface *surface = glfuncs::instance()->load_image(filename);
00158                                 SDL_LockSurface(surface);
00159                                 Uint32 pixel=*((Uint32*)surface->pixels);
00160                                 
00161                                 //cerr << (int) pixel << endl;
00162 
00163                                 SDL_UnlockSurface(surface);
00164                                 SDL_FreeSurface(surface);
00165 
00166                                 TEXTURES[pixel] = sprite;
00167                         }
00168                         else
00169                                 continue;
00170                 }
00171                 while( _findnext( hFile, &file ) == 0 );
00172 
00173                 _findclose( hFile );
00174         }
00175 }
00176 
00177 void Level::levelLoad(std::string filenamebase)
00178 {
00179         _filenamebase = filenamebase;
00180 
00181         levelTextureLoad(filenamebase);
00182         levelObjectLoad(filenamebase);
00183         levelSpecsLoad(filenamebase);
00184 
00185 
00186         //FIXME (Have the player object register this itself) 
00187         //This will require a text file for each level (which will have to be loaded here)
00188         //goudy1 is the id of the player
00189         _player = (Player *)_ids["goudy1"];
00190 
00191         Screen::instance()->registerFollowObj( (Object*)_player );
00192         Control::registerController((Object*)_player);
00193 
00194         //CommandManager::instance()->startPlaying("scripts/newDemo.txt");
00195         //CommandManager::instance()->startRecording();
00196 }
00197 
00198 void Level::levelSpecsLoad(std::string filenamebase)
00199 {
00200         string specsFilename = filenamebase + ".txt";
00201         List *specsList = Parser::parse(specsFilename);
00202 
00203         List *specs = specsList;
00204         
00205         while(!specs->empty()) {
00206                 List *current = specs->firstList();
00207 
00208                 Object *object = getObject(current->firstString());
00209                 object->load(current->rest());
00210 
00211                 specs = specs->rest();
00212         }
00213 
00214         delete specsList;
00215 }
00216 
00217 void Level::levelObjectLoad(std::string filenamebase)
00218 {
00219         string objFilename = filenamebase + "obj.bmp";
00220         SDL_Surface *surface = glfuncs::load_image(objFilename);
00221         SDL_LockSurface(surface);
00222 
00223         _height = surface->h*tileHeight;
00224         _width = surface->w*tileWidth;
00225 
00226         Uint32* objectPixels = (Uint32*)surface->pixels;
00227 
00228         //int maxoffset = surface->h*surface->w;
00229         for(int i=0; i < surface->h ; i++ ){
00230                 for( int j=0 ; j < surface->w ;j++){
00231 
00232                         if(OBJECTS[objectPixels[i*surface->w+j]] != "")
00233                         {
00234                                 Object* o = Object::loadObject(OBJECTS[objectPixels[i*surface->w+j]], j*tileWidth, i*tileHeight);
00235                                 string id = o->id();
00236                                 
00237                                 //Append a number to the end of objects so we get EasyEnemy1, EasyEnemy2, ...
00238                                 int i = 0;
00239                                 do
00240                                 {
00241                                         i++;
00242                                         stringstream num;
00243                                         num << i;
00244                                         o->setId(id+num.str());
00245                                         //map<string,Object *>::iterator j = _ids.find(o->id());
00246 
00247                                 //}while (_ids.find(o->id()) != _ids.end());
00248                                 } while(_ids[o->id()] != NULL);
00249 
00250                                 cerr << o->id() << endl;
00251 
00252                                 addObject(o, _objects);
00253                         }
00254                 }
00255         }
00256 
00257         SDL_UnlockSurface(surface);
00258         SDL_FreeSurface(surface);
00259 }
00260 
00261 
00262 void Level::levelTextureLoad(std::string filenamebase)
00263 {
00264         string texFilename = filenamebase + "tex.bmp";
00265         string colFilename = filenamebase + "col.bmp";
00266         string backFilename = filenamebase + "back.png";
00267         SDL_Surface *surface = glfuncs::load_image(texFilename);
00268         SDL_Surface* colSurface = glfuncs::load_image( colFilename );
00269 
00270         SDL_LockSurface(surface);
00271         SDL_LockSurface(colSurface);
00272 
00273         Tile* t = NULL;
00274 
00275         _height = surface->h*tileHeight;
00276         _width = surface->w*tileWidth;
00277         _tiles = vector< Tile* >( _height*_width, t );
00278         _background = new Background( backFilename, 0.5 );
00279         _background->setHeight( _height );
00280         _background->setWidth( _width );
00281 
00282         Uint32* texturePixels = (Uint32*)surface->pixels;
00283         Uint32* colPixels = (Uint32*)colSurface->pixels;
00284         Uint32 colPixel;
00285 
00286 
00287         //int maxoffset = surface->h*surface->w;
00288         for(int i=0; i < surface->h ; i++ ){
00289                 for( int j=0 ; j < surface->w ;j++){
00290                         if(TEXTURES[texturePixels[i*surface->w+j]]!=NULL)
00291                         {
00292                                 t = new Tile(   TEXTURES[texturePixels[i*surface->w+j]]->instance(), 
00293                                         true, j*tileWidth, i*tileHeight);
00294 
00295                                 colPixel = colPixels[ i*colSurface->w + j ];
00296                                 if( colPixel == Level::WALKBEHIND )
00297                                 {
00298                                         t->setCollidable( false );
00299                                         t->setDepth( 5 );
00300                                 } else if( colPixel == Level::WALKINFRONT )
00301                                 {
00302                                         t->setCollidable( false );
00303                                         t->setDepth( -1 );
00304                                 } else if( colPixel == Level::WALKINTO )
00305                                 {
00306                                         t->setCollidable( true );
00307                                         t->setDepth( 0 );
00308                                 }
00309 
00310                                 registerTile( t, i, j );
00311                         }
00312                 }
00313         }
00314 
00315         SDL_UnlockSurface(surface);
00316         SDL_UnlockSurface(colSurface);
00317         SDL_FreeSurface(surface);
00318         SDL_FreeSurface(colSurface);
00319 }
00320 
00321 bool Level::update()
00322 {
00323         Object* o;
00324 
00325         while( !_deleteQueue.empty() )
00326         {
00327                 o = _deleteQueue.front();
00328                 _deleteQueue.erase( remove( _deleteQueue.begin(), _deleteQueue.end(), o ), _deleteQueue.end() ); 
00329                 deleteObject( o );
00330 
00331                 if(o == this->_player)
00332                 {
00333                         // this early return is important for dying to work properly
00334                         _player = NULL;
00335                         return false;
00336                 }
00337 
00338         }
00339 
00340         while( !_addQueue.empty() )
00341         {
00342                 o = _addQueue.front();
00343                 addObject( o, _objects );
00344                 _addQueue.pop();
00345         }
00346 
00347         CommandManager::instance()->startTimestep();
00348 
00349         Control::update();
00350         Screen::instance()->update();
00351 
00352         for( vector< Object* >::iterator i = _objects.begin(); i != _objects.end(); i++ )
00353         {
00354                 (*i)->update();
00355         }
00356         return true;
00357 }
00358 
00359 void Level::draw()
00360 {
00361         // Draw background
00362         _background->draw();
00363 
00364         // Draw all drawable objects
00365         for( vector< Object* >::iterator i = _drawnObjects.begin(); i != _drawnObjects.end(); i++ )
00366         {
00367                 (*i)->draw();
00368         }
00369 
00370         drawHUD();
00371 
00372         if(_cutScene) {
00373                 Screen::instance()->drawCutScene(_cutSceneText);
00374         }
00375 }
00376 
00377 void Level::drawHUD()
00378 {
00379         SDL_Rect raster;
00380 
00381         Sprite *health = Sprite::loadSprite("sprites/health.png");
00382         Sprite *heart = Sprite::loadSprite("sprites/heart.png");
00383 
00384         raster.x = 5;
00385         raster.y = 5;
00386 
00387         health->draw(raster.x,raster.y,Sprite::SCREEN);
00388 
00389         raster.x += health->width() + 2;
00390         raster.y += 5;
00391 
00392         for(int i = 0; i < _player->getHealth(); i++) {
00393                 heart->draw(raster.x,raster.y,Sprite::SCREEN);
00394                 raster.x += heart->width() + 2;
00395         }
00396 
00397         glfuncs::instance()->glDisable(GL_TEXTURE_2D);
00398         raster.x = 710;
00399         raster.y = 30;
00400         glfuncs::instance()->glRasterPos2f(raster.x,raster.y);
00401 
00402         stringstream score;
00403         score << "Score: ";
00404         score << _score;
00405         glfuncs::instance()->glPrint(score.str());
00406         glfuncs::instance()->glEnable(GL_TEXTURE_2D);
00407 }
00408 
00409 // Schedule an object to be added to the level
00410 void Level::registerObject( Object* o )
00411 {
00412         _addQueue.push( o );
00413 }
00414 
00415 void Level::registerTile( Tile* t, int h, int w )
00416 {
00417         if( t->collidable() )
00418                 _tiles[ h*_width + w ] = t;
00419 
00420         // Add to _drawnObjects vector in depth sorted order
00421         vector< Object* >::iterator i = _drawnObjects.begin();
00422                 
00423         while( i != _drawnObjects.end() && t->getDepth() > (*i)->getDepth() )
00424                 i++;
00425 
00426         _drawnObjects.insert( i, t );
00427 }
00428 
00429 // Add the object to _drawnObjects, sorted in depth ordering,
00430 // then add the object to vec for collision detection
00431 void Level::addObject( Object* o, std::vector< Object* >& vec )
00432 {
00433         // Add to collision detection vector
00434         vec.push_back( o );
00435 
00436         // Add to _drawnObjects vector in depth sorted order
00437         vector< Object* >::iterator i = _drawnObjects.begin();
00438                 
00439         while( i != _drawnObjects.end() && o->getDepth() > (*i)->getDepth() )
00440                 i++;
00441 
00442         _drawnObjects.insert( i, o );
00443         _ids[o->id()] = o;
00444 
00445         /*
00446         cerr << "Registering : " << endl;
00447         cerr << o->id() << endl;
00448         cerr << o->getDepth() << endl;
00449         cerr << j << endl << endl;
00450         */
00451 }
00452 
00453 Object *Level::getObject( std::string id )
00454 {
00455         return _ids[id];
00456 }
00457 
00458 Level *Level::instance()
00459 {
00460         if(!_instance)
00461                 return new Level();
00462         else
00463                 return _instance;
00464 }
00465 
00466 void Level::scheduleDelete( Object* o )
00467 {
00468         _deleteQueue.push_back( o );
00469 }
00470 
00471 void Level::deleteObject( Object* o )
00472 {
00473         _objects.erase( remove( _objects.begin(), _objects.end(), o ), _objects.end() ); 
00474         _drawnObjects.erase( remove( _drawnObjects.begin(), _drawnObjects.end(), o ), _drawnObjects.end() ); 
00475         delete o;
00476 }
00477 
00478 
00479 void Level::setCutScene(bool cutScene)
00480 {
00481         _cutScene = cutScene;
00482 }
00483 
00484 Mix_Chunk* Level::getSound( std::string filename )
00485 {
00486         assert( _sounds.find( filename ) != _sounds.end() );
00487         return _sounds[ filename ];
00488 }
00489 
00490 void Level::loadSound( std::string filename )
00491 {
00492         // If the sound isn't already in the map, load it in
00493         if( _sounds.find( filename ) == _sounds.end() )
00494         {
00495                 _sounds[ filename ] = Mix_LoadWAV( filename.c_str() );
00496         }
00497 }

Generated on Sat Apr 22 15:05:20 2006 for ProjectX by  doxygen 1.4.6-NO