Wednesday, December 29, 2010

Code::Blocks(5) C++ SDL and Life "life.cpp"

Here is the code for the main program file, just copy and paste into file life.cpp in the project, then save the project:

#include <SDL/SDL.h> //SDL library
#include <SDL/SDL_image.h> //+SDL_image library (I use it for loading .png files)

#include "engine.h" // The simple engine class

#include <sstream> // I use it to work with text streams

int main ( int argc, char** argv ) //when you use a SDL c++ app you have to initialize main that way

Engine myengine; //Create a object from the type "Engine"
myengine.SetVga(); //Start graphics mode
myengine.LoadTileset(); //Load the image tileset to a SDLSurface

std::stringstream text; //Variable used to display text
Uint8 CellMap[50][50]; //The cell map, here qe store the cell state
Uint8 x,y; //variables used to travel across the cell array
int xmax, ymax; //Max size of tiles to display on screen
Uint8 Counter; //Counter of the surrounding cells
bool Paused; //Game paused?

Paused=false;//Let's start with the game running

xmax=myengine.ScreenX / myengine.TileSize; //calculate maximun number of cells (x-width)
ymax=myengine.ScreenY / myengine.TileSize; //calculate maximun number of cells (y-height)

 for (x=0;x<50;x++){
    for (y=0;y<50;y++){
        CellMap[x][y]=0; //clean the cell map so everything is "0"
    };//end y for
 };//end x for

//I put just 5 cells, into a "slider" configuration

    // program main loop
    bool done = false;
    while (!done) // will loop infinite times until we set done = true
        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
            // check for messages
            switch (event.type)
                // exit if the window is closed
            case SDL_QUIT:
                done = true;

                // check for keypresses
            case SDL_KEYDOWN:
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
            } // end switch
        } // end of message processing

myengine.Frames++;//increase frame counter

myengine.FillColour(200,200,200);//Clear screen with grey color
if (myengine.TimeElapsed()>=1000) // every second (1000ms)
    myengine.UpdateTimer(); // reset time counter
    myengine.FPS = myengine.Frames; // update the frames per second counter
    myengine.Frames=0; // reset frame counter

    text.str(""); //clean variable "text"
    text << "FPS:" << myengine.FPS; //will set text = "FPS: number"
    SDL_WM_SetCaption(  text.str().c_str(), NULL ); //set the title of the window to "text">>"FPS: number"

if (Paused==false){ //If the game is not paused, process cell map (step 1)
    for (x=1;x<=(xmax-1);x++){
        for (y=1;y<=(ymax-1);y++){
            Counter=0;//now we count the number of surrounding cells
            if (CellMap[x-1][y-1]==1 or     CellMap[x-1][y-1]==3)Counter++;
            if (CellMap[x-1][y]==1 or       CellMap[x-1][y]==3)Counter++;
            if (CellMap[x-1][y+1]==1 or     CellMap[x-1][y+1]==3)Counter++;
            if (CellMap[x][y-1]==1 or       CellMap[x][y-1]==3)Counter++;
            if (CellMap[x][y+1]==1 or       CellMap[x][y+1]==3)Counter++;
            if (CellMap[x+1][y-1]==1 or     CellMap[x+1][y-1]==3)Counter++;
            if (CellMap[x+1][y]==1 or       CellMap[x+1][y]==3)Counter++;
            if (CellMap[x+1][y+1]==1 or     CellMap[x+1][y+1]==3)Counter++;

            if (CellMap[x][y]==0 and Counter==3)CellMap[x][y]=2; //Born
            if (CellMap[x][y]==1){
                if (Counter<2 or Counter >3)CellMap[x][y]=3; //Die

            //myengine.BlitTileset(x,y,CellMap[x][y]);  >>DISABLED

        }; //End for y
    };  //End for x

    //myengine.Flip();                                  >>DISABLED

}//enf if pause
}//end if time elapsed >= 1 second

for (x=1;x<=(xmax-1);x++){//Process cell map (step 2)
    for (y=1;y<=(ymax-1);y++){

        if (CellMap[x][y]==2)CellMap[x][y]=1; //Born
        if (CellMap[x][y]==3)CellMap[x][y]=0; //Die

        myengine.BlitTileset(x,y,CellMap[x][y]); //Display cell on screen

myengine.UpdateMouse();//update x and y mouse position + mouse buttons pressed

if(myengine.MouseButtons ==SDL_BUTTON(SDL_BUTTON_LEFT)){//Pressed left mouse button
    int sx,sy;
    /*   That code shows how to do a simple mouse maping:
    we have the physicall position where mouse is (myengine.MouseX,myengine.Mousey)
    but we need to know which tile correspond to that physicall position
    so we make an integer division between mouse (x, y) and the tilesize,
    the resulting sx, and sy is the tile where we have our mouse cursor    */

    //swap cell state: dead>living living>dead
    if(CellMap[sx+1][sy+1]==0) //It the cell is dead
            CellMap[sx+1][sy+1]=1;//Cell is living
        }else{ //else cell is living
            CellMap[sx+1][sy+1]=0;//kill the cell

    text.str("");//clean variable "text"
    text << "Left mouse pressed at:X:" << sx <<  " Y: "<< sy;//will set text = "Left mouse pressed at:X: number Y: number"
    SDL_WM_SetCaption(  text.str().c_str(), NULL );//set the title of the window to "text">>"Left mouse pressed at:X: number Y: number"

};//end left mouse button if

if(myengine.MouseButtons ==SDL_BUTTON(SDL_BUTTON_RIGHT) ){//Pressed right mouse button
    if (Paused ==true)//if the game is paused
            Paused =false;//continue game
            Paused=true;//else the game is running , pause it
   if (Paused==true) SDL_WM_SetCaption( "PAUSED" , NULL );//if the game is paused, show it in the title bar
};//end right mouse button if

myengine.Flip();//Finally, update the screen from the back buffer :)
myengine.Wait(1); //prevent application from freezing OS
    } // end main loop

myengine.~Engine(); //Destroy object myengine >> that will free the SDSSurfaces and close SDL

return 0; //Everything is ok

No comments: