Advertisement
thecplusplusguy

Mapcreator for the simple sidescroller(SDL) - mapcreator.cpp

Aug 7th, 2011
797
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.86 KB | None | 0 0
  1. //This example program is created by thecplusplusuy for demonstration purposes (no video about this, I think, it's too simple, and not show nothing new, but I put the source up, to make a complete program with the simple sidescroller (there is video about that)). It's a map-creator for the simple sidescroller game.
  2. //http://www.youtube.com/user/thecplusplusguy
  3. //Free source, modify if you want, LGPL licence (I guess), I would be happy, if you would not delete the link
  4. //so other people can see the tutorial
  5. //this file is mapcreator.cpp
  6. #include "mapcreator.h" //we include the header, which we have created
  7.  
  8. mapcreator::mapcreator()
  9. {
  10.     SDL_Init(SDL_INIT_EVERYTHING);  //don't forget to initialize the SDL, it's allocate the needed memory. We initialize everything
  11.     screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);  //open our window
  12.     background=load_image("endless.bmp");   //open our 3 image
  13.     blocks=load_image("blocks.bmp");
  14.     enemy=load_image("enemy.bmp");
  15.     enemy_rect.x=enemy_rect.y=0;    //we set the coordinate of the enemy (it's not animated when you make the map, only in the game)
  16.     enemy_rect.w=enemy_rect.h=40;
  17.     for(int i=0;i<NUMRECT;i++)  //we set the coordinate of the blocks (tiles)
  18.     {
  19.         blocks_rect[i].x=i*50;  //only the x coordinate is change
  20.         blocks_rect[i].y=0;         //we have just 1 row of tiles
  21.         blocks_rect[i].w=50;        //width=50
  22.         blocks_rect[i].h=50;        //hight=50
  23.  
  24.     }
  25.     current=0;  //we use the current block 0 (green grass for me :D)
  26.     for(int i=0;i<10;i++)   //we make the default map (10*50=500 which is just a little bigger then the 480 height of the window)
  27.     {
  28.         std::vector<int> vec;   //the map is represented by a vector in a vector (a multidimensional dynamically allocated array)
  29.         for(int j=0;j<13;j++)   //13*50=650 which is just a little bigger then the with of the window (640)
  30.             vec.push_back(0);       //default we put nothing in everywhere
  31.         map.push_back(vec);     //and than add it
  32.     }
  33.     coord.x=0;  //we set the default coordinates, nothing to explain here
  34.     coord.y=0;
  35.     coord.w=640;
  36.     coord.h=480;
  37.     camera.x=0;
  38.     camera.y=0;
  39.     camera.w=640;
  40.     camera.h=480;
  41.     timeshift=0;
  42. }
  43.  
  44. mapcreator::~mapcreator()
  45. {
  46.     SDL_FreeSurface(background);    //free the surfaces and escape from SDL
  47.     SDL_FreeSurface(blocks);
  48.     SDL_FreeSurface(enemy);
  49.     SDL_Quit();
  50. }
  51.  
  52. void mapcreator::start()    //the main loop is in here
  53. {
  54.     Uint32 start;   //to regulate the FPS
  55.     const int FPS=30;   //we use 30 FPS (if you want you can use SDL_WaitEvent, so you don't need to specify the FPS)
  56.     bool running=true;  //is the program running?
  57.     SDL_Event event;
  58.     int x,y;    //the x,y coordinate of the mouse cursor relative to the window
  59.     while(running)
  60.     {
  61.         start=SDL_GetTicks();   //we fill start with the current time
  62.         while(SDL_PollEvent(&event))    //while there are events
  63.         {
  64.             switch(event.type)  //which event is it?
  65.             {
  66.                 case SDL_QUIT:
  67.                     running=0;  //if we exited, exit from the program
  68.                     break;
  69.                 case SDL_MOUSEBUTTONDOWN:   //if a mouse button is down then
  70.                     if(event.button.button==SDL_BUTTON_RIGHT)   //if this button is the right mouse button
  71.                     {
  72.                         x=event.button.x;   //get the coordinate
  73.                         y=event.button.y;
  74.                         x=x-(x%50); //Little trickey, but basically we round down to the nearest 50 for example
  75.                         y=y-(y%50); //if we are at 143 x coordinate then we set x to 100 if we are at 49 coordinate we set x to 0
  76.                         //if we are at 50 coordinate we leave it as 50, we ded the same to y too.
  77.                         current++;  //we increase the current (show the next block)
  78.                         if(current>=NUMRECT)    //if we go too far, set it back to -2 (-2 enemy, -1 nothing)
  79.                             current=-2;
  80.                     }else if(event.button.button==SDL_BUTTON_LEFT)  //if the left button is pressed
  81.                     {
  82.                         x=event.button.x;   //get the current coordinates
  83.                         y=event.button.y;
  84.                         x=x-(x%50);//and do the same thing again with the x and y coordinates (round down to the nearest number dividable by 50)
  85.                         y=y-(y%50);
  86.                         map[((int)(y/50)+coord.y/50)][((int)(x/50)+coord.x/50)]=current+1;
  87.                         //that's a little trickey again, but all we do in here is get the index for the tile, and then add our absolute coordinate to it
  88. //for example, if we are at 0,0 coordinate, and we click at 150,200 coordinate, than change the map[3][4] coordinate to the current tile
  89. //you may noticed, it's current+1, that's because originally the 0 is the nothing, and the first tile (according to C rules the 0th) is the 1st
  90. //a little problem, nothing more. So another example, if we are at 1000,0 coordinate and we click at 150,200, than map[3][24]=current+1
  91.                     }
  92.                     break;
  93.                 case SDL_MOUSEMOTION:   //if we moved the mouse
  94.                     x=event.motion.x;   //we get the coordinates again
  95.                     y=event.motion.y;
  96.                     x=x-(x%50); //and we round to the nearest 50 again
  97.                     y=y-(y%50);
  98.                     break;
  99.                     case SDL_KEYDOWN:
  100.                         if(event.key.keysym.sym==SDLK_s)    //if the s key is down
  101.                             save(); //save the map
  102.                         break; 
  103.             }
  104.         }
  105. //      std::cout << x << std::endl;
  106.                     if(x>550)   //if we are at the right edge of the screen
  107.                     {
  108.                         if(timeshift==0)    //and the timeshift is 0
  109.                         {
  110.                             timeshift=20;   //change it to 20 (it's mean, that we move the camera 20 frame later)
  111.                             coord.x+=50;    //move the camera
  112.                             camera.x+=50; //move the camera
  113.                             if(camera.x>=2000-640)  //if the background have to be reapeted
  114.                                 camera.x=0; //repeat it
  115.                             for(int i=0;i<map.size();i++)   //we add on coloumn of nothing to the end of the map
  116.                             {
  117.                                 map[i].push_back(0);
  118.                             }
  119.                         }else
  120.                             timeshift--;    //just decrease the timeshift every time, it's not equal to 0
  121.                     }
  122.                     if(x<50 && coord.x>=50) //we do the same thing in the other direction too
  123.                     {
  124.                         if(timeshift==0)
  125.                         {
  126.                             timeshift=20;
  127.                             coord.x-=50;
  128.                             camera.x-=50;
  129.                             if(camera.x<=0)
  130.                                 camera.x=2000-640;
  131.                         }else
  132.                             timeshift--;
  133.                     }
  134.  
  135.         SDL_BlitSurface(background,&camera,screen,NULL);    //we draw the background at the correct position
  136.                                                                                                             //(watch the scrollable background tutorial, if it's not clear
  137.         showmap();  //and we show the map
  138.         SDL_Rect tmp={x,y};
  139.         if(current>=0)  //if the current is not 0 (or less then except the enemy)
  140.             SDL_BlitSurface(blocks,&blocks_rect[current],screen,&tmp);  //draw the block, which we are holding to the position of the mouse cursor
  141.         else if(current==-2)    //if it's an enemy
  142.             SDL_BlitSurface(enemy,&enemy_rect,screen,&tmp); //draw it
  143.         SDL_Flip(screen);   //show the screen
  144.         if(1000/FPS>(SDL_GetTicks()-start)) //regulate the FPS (watch regulate FPS tutorial, if it's not clear)
  145.             SDL_Delay(1000/FPS-(SDL_GetTicks()-start));
  146.     }
  147. }
  148.  
  149. SDL_Surface* mapcreator::load_image(const char* c)  //load the image
  150. {
  151.     SDL_Surface* tmp=SDL_LoadBMP(c);    //load the BMP file
  152.     SDL_Surface* tmp2=SDL_DisplayFormat(tmp);   //then convert it to the format of the screen
  153.     SDL_FreeSurface(tmp);   //free it, we don't need it anymore
  154.     SDL_SetColorKey(tmp2,SDL_SRCCOLORKEY,SDL_MapRGB(screen->format,0x00,0xff,0xff)); //set a color key, so 00ffff is transparent
  155.     return tmp2;    //return a pointer to the surface
  156. }
  157.  
  158. void mapcreator::showmap()
  159. {
  160.     //it should be familiar to you, because basically it's the same as in the sidescroller game
  161.     int start=(coord.x-(coord.x%50))/50;    //calculate the first number which is dividable by 50 and it's in the screen
  162.     int end=(coord.x+coord.w+(50-(coord.x+coord.w)%50))/50; //round last number, dividable by 50, which is in the screen
  163.     if(end>map[0].size())   //if the end is too big
  164.         end=map[0].size();  //set it to the size of the map
  165.     if(start<0) //if start is too small
  166.         start=0;    //set it to the first element
  167.     for(int i=0;i<map.size();i++)
  168.         for(int j=0;j<map[0].size();j++)    //go through the visible map
  169.             if(map[i][j]!=0)    //if it's not "nothing"
  170.             {
  171.                 if(map[i][j]==-1)   //if it's an enemy
  172.                 {
  173.                     //draw it
  174.                     SDL_Rect blockrect = {0,0,40,40};
  175.                     SDL_Rect destrect= {j*50-coord.x,i*50};
  176.                     SDL_BlitSurface(enemy,&blockrect,screen,&destrect);
  177.                         continue;   //and don't draw anything else
  178.                 }
  179.                 //else draw the block which is needed
  180.                 SDL_Rect blockrect = {(map[i][j]-1)*50,0,50,50};
  181.                 SDL_Rect destrect= {j*50-coord.x,i*50};
  182.                 SDL_BlitSurface(blocks,&blockrect,screen,&destrect);
  183.             }
  184. }
  185.  
  186.  
  187. void mapcreator::save()
  188. {
  189.     char c[30]; //filename
  190.     sprintf(c,"%d",time(0));    //we use the current time in seconds from 1970.01.01 (it's always changing, so every time it will get a uniqe filename)
  191.     //pretty basic, but easy and fairly effective
  192.     strcat(c,".map");   //we cat the map extension to the end of the number
  193.     std::ofstream out(c);   //open the filestream for output with the current name
  194. //  std::cout << "Saved" << std::endl; 
  195.     out << map[0].size() << " " << map.size() << std::endl; //first we write out the size of the map
  196.     for(int i=0;i<map.size();i++)   //go through the array
  197.     {
  198.         for(int j=0;j<map[0].size();j++)
  199.         {
  200.             out << map[i][j] << " ";    //and write the tile number separated by space
  201.         }
  202.         out << std::endl;
  203.     }
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement