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

terrain.cpp

Go to the documentation of this file.
00001 #include <SDL/SDL.h>
00002 #include <SDL/SDL_rotozoom.h>
00003 #include <SDL/SDL_gfxPrimitives.h>
00004 
00005 #include "constants.h"
00006 #include "terrain.h"
00007 #include "random.h"
00008 #include "util.h"
00009 #include "starfield.h"
00010 
00011 Terrain :: Terrain( int w, int h, bool drawTop, bool drawBottom )
00012 {
00013         sWidth = w;
00014         sHeight = h;
00015         speed = 1;
00016         segSize = sWidth/(MAPSIZE-2)+1;
00017         this->drawTop = drawTop;
00018         this->drawBottom = drawBottom;
00019 
00020         stars = new StarField( true );
00021 
00022         SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, sWidth + 20, sHeight, 32,
00023                                                                                         0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000);
00024         terrainSurface = SDL_DisplayFormat( tmp );
00025         SDL_FreeSurface( tmp );
00026 
00027         initTerrain();
00028 
00029 }
00030 
00031 Terrain :: ~Terrain()
00032 {
00033         SDL_FreeSurface( terrainSurface );
00034         delete stars;
00035 }
00036 
00037 void Terrain :: initTerrain()
00038 {
00039         dir = 1;
00040         offset = 0;
00041 
00042         maxHeight = 50;
00043 
00044         mapTop[0] = (int)(nextInt(50)) + 5;
00045         mapBottom[0] = sHeight - (maxHeight - mapTop[0]);
00046         for ( int i = 1 ; i < MAPSIZE ; ++i )
00047                 setPoint( i );
00048 
00049         SDL_FillRect( terrainSurface, 0, 0 );
00050 
00051         // Draw Terrain into surface
00052         Sint16 px[5];
00053         Sint16 py[5];
00054 
00055         for ( int i = 0 ; i < MAPSIZE ; ++i )
00056         {
00057                 int left = (i*segSize);
00058                 int right = ((i+1)*segSize);
00059                 px[0] = left;
00060                 py[0] = mapTop[i];
00061                 px[1] = right;
00062                 py[1] = mapTop[i+1];
00063                 px[2] = right;
00064                 py[2] = 0;
00065                 px[3] = left;
00066                 py[3] = 0;
00067 
00068                 if ( drawTop )
00069                 {
00070                         // Only display top landscape if not running FLY_GAME
00071                         filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00072                 }
00073 
00074                 if ( drawBottom )
00075                 {
00076                         py[0] = mapBottom[i];
00077                         py[1] = mapBottom[i+1];
00078                         py[2] = sHeight;
00079                         py[3] = sHeight;
00080                         filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00081                 }
00082 
00083         }
00084 
00085 
00086 }
00087 
00088 void Terrain :: moveTerrain( int amountToMove )
00089 {
00090         stars->move();
00091 
00092         offset += amountToMove;
00093         speed = offset/segSize;
00094 
00095         if ( offset >= segSize )
00096         {
00097                 for ( int i = 0 ; i < (MAPSIZE)-speed ; ++i )
00098                 {
00099                         mapTop[i] = mapTop[i+speed];
00100                         mapBottom[i] = mapBottom[i+speed];
00101                 }
00102 
00103                 for ( int i = (MAPSIZE)-speed ; i < MAPSIZE ; ++i )
00104                 {
00105                         setPoint( i );
00106                 }
00107 
00108                 SDL_Rect dst;
00109                 dst.x = offset;
00110                 dst.y = 0;
00111                 dst.w = sWidth;
00112                 dst.h = sHeight;
00113 
00114                 SDL_Rect dst2;
00115                 dst2.x = 0;
00116                 dst2.y = 0;
00117 
00118                 SDL_BlitSurface(terrainSurface, &dst, terrainSurface, &dst2 );
00119 
00120                 dst.x = sWidth-5;
00121                 dst.y = 0;
00122                 dst.w = offset;
00123                 dst.h = sHeight;
00124                 SDL_FillRect( terrainSurface, &dst, 0 );
00125                 for ( int i = (MAPSIZE-1) - speed -1; i < MAPSIZE-1 ; ++i )
00126                 {
00127                         Sint16 px[4];
00128                         Sint16 py[5];
00129                         int left = ((i-1)*segSize);
00130                         int right = ((i)*segSize);
00131                         // printf( "left = %d, right = %d\n", left, right );
00132 
00133                         px[0] = left;
00134                         py[0] = mapTop[i];
00135                         px[1] = right;
00136                         py[1] = mapTop[i+1];
00137                         px[2] = right;
00138                         py[2] = 0;
00139                         px[3] = left;
00140                         py[3] = 0;
00141 
00142                         if ( drawTop )
00143                         {
00144                                 // Only display top landscape if not running FLY_GAME
00145                                 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00146                         }
00147 
00148                         if ( drawBottom )
00149                         {
00150                                 py[0] = mapBottom[i];
00151                                 py[1] = mapBottom[i+1];
00152                                 py[2] = sHeight;
00153                                 py[3] = sHeight;
00154                                 filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 );
00155                         }
00156                 }
00157 
00158                 offset -= speed*segSize;
00159 
00160         }
00161 
00162 }
00163 
00164 void Terrain :: setPoint( int point )
00165 {
00166         if ( nextInt( 100 ) >= 80 )
00167                 dir *= -1;
00168 
00169         mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 ));
00170         if ( mapTop[point] < 0 )
00171         {
00172                 mapTop[point] = 0;
00173                 dir *= -1;
00174         }
00175         else if ( mapTop[point] >= maxHeight )
00176         {
00177                 mapTop[point] = maxHeight;
00178                 dir *= -1;
00179         }
00180 
00181         mapBottom[point] = sHeight - (maxHeight - mapTop[point]);
00182 }
00183 
00184 void Terrain :: increaseMaxHeight( int amount )
00185 {
00186         maxHeight += amount;
00187 }
00188 
00189 void Terrain :: drawTerrain( SDL_Surface *screen )
00190 {
00191         // Blit terrain surface onto screen
00192 
00193         SDL_Rect dst;
00194         dst.x = offset;
00195         dst.y = 0;
00196         dst.w = sWidth;
00197         dst.h = sHeight;
00198 
00199         SDL_Rect dst2;
00200         dst2.x = 0;
00201         dst2.y = 0;
00202 
00203     SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 );
00204 
00205     stars->draw( screen );
00206 }
00207 
00208 bool Terrain :: checkCollision( int x, int y, int h )
00209 {
00210         if ( y < 0 || y > sHeight )
00211                 return true;
00212 
00213         // First get segment that matches x
00214         SDL_LockSurface( terrainSurface );
00215 
00216         Uint32 c = getpixel( terrainSurface, x, y );
00217 
00218         SDL_UnlockSurface( terrainSurface );
00219 
00220         if ( c == 0 )
00221                 return false;
00222         else
00223                 return true;
00224 }
00225 
00226 
00227 // Test
00228 #ifdef DEBUG_TERRAIN
00229 SDL_Surface *screen;
00230 Terrain *terrain;
00231 
00232 void go()
00233 {
00234         // Initialize SDL
00235         if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
00236         {
00237                 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
00238                 exit(1);
00239         }
00240         atexit(SDL_Quit);
00241 
00242         int videoflags = SDL_SWSURFACE ;
00243 
00244         if ( (screen=SDL_SetVideoMode(280, 320,32,videoflags)) == NULL )
00245         {
00246                 fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError());
00247                 exit(2);
00248         }
00249 
00250         terrain = new Terrain( 240, 320 );
00251 
00252         bool done = false;
00253         while ( !done )
00254         {
00255                 SDL_FillRect( screen, 0, 0 );
00256                 terrain->drawTerrain( screen );
00257                 terrain->moveTerrain( 5 );
00258 
00259                 SDL_Flip( screen );
00260 
00261                 SDL_Delay( 5 );
00262 
00263                 SDL_Event event;
00264                 while ( SDL_PollEvent(&event) )
00265                 {
00266                         switch (event.type)
00267                         {
00268                                 case SDL_KEYDOWN:
00269                                         // Escape keypress quits the app
00270                                         if ( event.key.keysym.sym != SDLK_ESCAPE )
00271                                         {
00272                                                 terrain->moveTerrain( 5 );
00273                                                 break;
00274                                         }
00275                                 case SDL_QUIT:
00276                                         done = 1;
00277                                         break;
00278                                 default:
00279                                         break;
00280                         }
00281                 }
00282         }
00283  }
00284 
00285 
00286 
00287 
00288 #ifdef __cplusplus
00289 extern "C"
00290 #endif
00291 int main( int argc, char *argv[] )
00292 {
00293         go();
00294 }
00295 
00296 #endif
00297 

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