User Tools

Site Tools


user:ccornair:portfolio:sysprogproject1

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
user:ccornair:portfolio:sysprogproject1 [2013/05/07 03:09] – [Execution] ccornairuser:ccornair:portfolio:sysprogproject1 [2013/05/07 03:15] (current) – [Reflection] ccornair
Line 1: Line 1:
 +======Project: PONG======
 +
 +
 +=====Objectives=====
 +the purpose is to learn the SDL libraries and build a pong game
 +=====Prerequisites=====
 +In order to successfully accomplish/perform this project, the listed resources/experiences need to be consulted/achieved:
 +
 +  install SDL libraries
 +
 +
 +=====Scope=====
 +I feel that this project will be tough and hope I am able to complete it by the end of the semester
 +
 +=====procedure=====
 +
 +I have commented my procedure in the code itself, see code section, I hope that was ok to do
 +
 +
 + 
 +
 +=====Code=====
 +Upon completion of the project, if there is an applicable collection of created code, place a copy of your finished code within <nowiki><code> </code></nowiki> blocks here.
 +
 +<code c>
 +
 +
 +//The headers
 +#include"SDL/SDL.h"
 +#include"SDL/SDL_image.h"
 +#include"SDL/SDL_ttf.h"
 +#include<string>
 +#include<stdio.h>
 +#include<math.h>
 +
 +
 +//The screen attributes
 +const int SCREEN_WIDTH = 640;
 +const int SCREEN_HEIGHT = 480;
 +const int SCREEN_BPP = 32;
 +
 +//The frame rate
 +const int FRAMES_PER_SECOND = 20;
 +
 +//The dimensions of the ball
 +const int BALL_WIDTH = 35;
 +const int BALL_HEIGHT = 35;
 +
 +//The dimensions of the paddles
 +const int PADDLE_WIDTH = 15;
 +const int PADDLE_HEIGHT = 85;
 +
 +//The surfaces
 +SDL_Surface *ball = NULL;
 +SDL_Surface *background = NULL;
 +SDL_Surface *screen = NULL;
 +SDL_Surface *paddleL = NULL;
 +SDL_Surface *paddleR = NULL;
 +
 +//The event structure
 +SDL_Event event;
 +
 +//The font
 +TTF_Font *font = NULL;
 +
 +//The color of the font
 +SDL_Color textColor = { 255, 255, 255 };
 +
 +//The left paddle that will move
 +class PaddleL
 +{
 +    private:
 +        
 +         //The velocity of left paddle
 +        int xVel, yVel;
 +        
 +    public:       
 +        //Initializes the variables for left paddle
 +        PaddleL();
 +        SDL_Rect boxL;     
 +        //Takes key presses and adjusts left paddle's velocity
 +        void handle_input();
 +        
 +        //Moves left paddle
 +        void move();
 +        
 +        //Shows left paddle on the screen
 +        void show();
 +};
 +
 +//The right paddle that will move
 +class PaddleR
 +{
 +    private:
 +        
 +        //The velocity of right paddle
 +        int xVel, yVel;
 +        
 +    public:
 +        
 +        //Initializes the variables for right paddle
 +        PaddleR();
 +        SDL_Rect boxR;   
 +        //Takes key presses and adjusts right paddle's velocity
 +        void handle_input();
 +        
 +        //Moves right paddle
 +        void move();
 +        
 +        //Shows right paddle on the screen
 +        void show();
 +};
 +
 +//The ball that will move around the screen
 +class Ball
 +{
 +    public:
 +        //Initializes the variables
 +        Ball();
 +        SDL_Rect collbox;
 +        int xVel, yVel;
 +        
 +        //Resets ball to center of screen
 +        void reset();
 +        
 +        //Takes key presses and adjusts the ball's velocity
 +        void handle_input();
 +        
 +        //Moves the ball
 +        void move();
 +        
 +        //Shows the ball on the screen
 +        void show();
 +};
 +
 +//The timer
 +class Timer
 +{
 +    private:
 +        //The clock time when the timer started
 +        int startTicks;
 +        
 +        //The ticks stored when the timer was paused
 +        int pausedTicks;
 +        
 +        //The timer status
 +        bool paused;
 +        bool started;
 +        
 +    public:
 +        //Initializes variables
 +        Timer();
 +        
 +        //The various clock actions
 +        void start();
 +        void stop();
 +        void pause();
 +        void unpause();
 +        
 +        //Gets the timer's time
 +        int get_ticks();
 +        
 +        //Checks the status of the timer
 +        bool is_started();
 +        bool is_paused();
 +};
 +
 +SDL_Surface *load_image( std::string filename )
 +{
 +    //The image that's loaded
 +    SDL_Surface* loadedImage = NULL;
 +    
 +    //The optimized surface that will be used
 +    SDL_Surface* optimizedImage = NULL;
 +    
 +    //Load the image
 +    loadedImage = IMG_Load(filename.c_str());
 +    
 +    //If the image loaded
 +    if(loadedImage != NULL)
 +    {
 +        //Create an optimized surface
 +        optimizedImage = SDL_DisplayFormat(loadedImage);
 +        
 +        //Free the old surface
 +        SDL_FreeSurface(loadedImage);
 +        
 +        //If the surface was optimized
 +        if(optimizedImage != NULL)
 +        {
 +            //Map the color key
 +            Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 255, 255, 255);
 +            
 +            //Set all pixels of color R 255, G 255, B 255 (white) to be transparent
 +            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
 +        }
 +    }
 +    
 +    //Return the optimized surface
 +    return optimizedImage;
 +}
 +
 +void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
 +{
 +    //Holds offsets
 +    SDL_Rect offset;
 +    
 +    //Get offsets
 +    offset.x = x;
 +    offset.y = y;
 +    
 +    //Blit
 +    SDL_BlitSurface(source, clip, destination, &offset);
 +}
 +
 +bool check_collision( SDL_Rect A, SDL_Rect B)
 +{
 +    //The sides of the rectangles
 +    int leftA, leftB;
 +    int rightA, rightB;
 +    int topA, topB;
 +    int bottomA, bottomB;
 +    
 +    //Calculate the sides of rect A and rect B
 +    leftA = A.x;
 +    rightA = A.x + A.w;
 +    topA = A.y;
 +    bottomA = A.y + A.h;
 +    
 +    leftB = B.x;
 +    rightB = B.x + B.w;
 +    topB = B.y;
 +    bottomB = B.y + B.h;
 +    
 +    //If any of the sides from A are outside of B
 +    if( bottomA <= topB)
 +    {
 +        return false;
 +    }
 +    
 +    if( topA >= bottomB )
 +    {
 +        return false;
 +    }
 +
 +    if( rightA<=leftB)
 +    {
 +        return false;
 +    }
 +    
 +    if( leftA>=rightB)
 +    {
 +        return false;
 +    }
 +    
 +    //If none of the sides from A are outside B
 +    return true;
 +}
 +
 +bool init()
 +{
 +    //Initialize all SDL subsystems
 +    if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
 +    {
 +        return false;
 +    }
 +    
 +    //Set up the screen
 +    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); 
 +    
 +    //If there was an error in setting up the screen
 +    if(screen == NULL)
 +    {
 +        return false;
 +    }
 +    
 +    //Initialize SDL_ttf
 +    if( TTF_Init() == -1 )
 +    {
 +        return false;
 +    }
 +    
 +    //Set the window caption
 +    SDL_WM_SetCaption("Hit space bar to begin", NULL);
 +    
 +    //If everything initialized fine
 +    return true;
 +}
 +
 +bool load_files()
 +{
 +    //Load the images
 +    ball = load_image("tennisBall.bmp");
 +    background = load_image("Background.bmp");
 +    paddleL = load_image("paddleRed.bmp");
 +    paddleR = load_image("paddleBlue.bmp");
 +    
 +    //Open the font
 +    font = TTF_OpenFont("lazy.ttf", 89);
 +    
 +    //If there was a problem in loading the font
 +    if(font == NULL)
 +    {
 +        return false;
 +    }
 +    
 +    //If there was a problem loading the ball
 +    if(ball == NULL)
 +    {
 +        return false;
 +    }
 +    
 +    //If there was a problem in loading the background
 +    if(background == NULL)
 +    {
 +        return false;
 +    }
 +    
 +    //If there was a problem in loading a paddle
 +    if(paddleL == NULL || paddleR == NULL)
 +    {
 +        return false;
 +    }
 +    
 +    //If everything loaded fine
 +    return true;
 +}
 +
 +void clean_up()
 +{
 +    //Free the surfaces
 +    SDL_FreeSurface(ball);
 +    SDL_FreeSurface(background);
 +    SDL_FreeSurface(paddleL);
 +    SDL_FreeSurface(paddleR);
 +    
 +    //Close the font
 +    TTF_CloseFont(font);
 +    
 +    //Quit SDL_ttf
 +    TTF_Quit();
 +    
 +    //Quit SDL
 +    SDL_Quit();
 +}
 +
 +PaddleL::PaddleL()
 +{
 +    //Initialize the offsets
 +    boxL.x = 0;
 +    boxL.y = SCREEN_HEIGHT/2 - PADDLE_HEIGHT/2;
 +    
 +    //Set the collision box's dimensions
 +    boxL.w = PADDLE_WIDTH;
 +    boxL.h = PADDLE_HEIGHT;
 +    
 +    //Initialize the velocity
 +    xVel = 0;
 +    yVel = 0;
 +}
 +
 +PaddleR::PaddleR()
 +{
 +    //Initialize the offsets
 +    boxR.x = 625;
 +    boxR.y = SCREEN_HEIGHT/2 - PADDLE_HEIGHT/2;
 +    
 +    //Set the collision box's dimensions
 +    boxR.w = PADDLE_WIDTH;
 +    boxR.h = PADDLE_HEIGHT;
 +    
 +    //Initialize the velocity
 +    xVel = 0;
 +    yVel = 0;
 +}
 +
 +void PaddleL::handle_input()
 +{
 +    //If a key was pressed 
 +    if( event.type == SDL_KEYDOWN )
 +    {
 +        //Adjust the velocity
 +        switch( event.key.keysym.sym )
 +        {
 +            case SDLK_a: yVel -= PADDLE_HEIGHT/9; break;
 +            case SDLK_z: yVel += PADDLE_HEIGHT/9; break;
 +        }
 +    }
 +    //If a key was released
 +    else if( event.type == SDL_KEYUP )
 +    {
 +        //Adjust the velocity
 +        switch( event.key.keysym.sym )
 +        {
 +            case SDLK_a: yVel += PADDLE_HEIGHT/9; break;
 +            case SDLK_z: yVel -= PADDLE_HEIGHT/9; break;
 +        }
 +    }
 +}
 +
 +void PaddleR::handle_input()
 +{
 +    //If a key was pressed 
 +    if( event.type == SDL_KEYDOWN )
 +    {
 +        //Adjust the velocity
 +        switch( event.key.keysym.sym )
 +        {
 +            case SDLK_UP: yVel -= PADDLE_HEIGHT/9; break;
 +            case SDLK_DOWN: yVel += PADDLE_HEIGHT/9; break;
 +        }
 +    }
 +    //If a key was released
 +    else if( event.type == SDL_KEYUP )
 +    {
 +        //Adjust the velocity
 +        switch( event.key.keysym.sym )
 +        {
 +            case SDLK_UP: yVel += PADDLE_HEIGHT/9; break;
 +            case SDLK_DOWN: yVel -= PADDLE_HEIGHT/9; break;
 +        }
 +    }
 +}
 +
 +void PaddleL::move()
 +{
 +    //Move the paddle up or down
 +    boxL.y += 2*yVel;
 +    
 +    //If the paddle went to far up or down
 +    if( (boxL.y<0) || (boxL.y + PADDLE_HEIGHT > SCREEN_HEIGHT) )
 +    {
 +        //Move back
 +        boxL.y -= 2*yVel;
 +    }
 +}
 +
 +void PaddleR::move()
 +{
 +    //Move the paddle up or down
 +    boxR.y += 2*yVel;
 +    
 +    //If the paddle went to far up or down
 +    if( (boxR.y<0) || (boxR.y + PADDLE_HEIGHT > SCREEN_HEIGHT) )
 +    {
 +        //Move back
 +        boxR.y -= 2*yVel;
 +    }
 +}
 +
 +void PaddleL::show()
 +{
 +    //Show the Paddle
 +    apply_surface(boxL.x, boxL.y, paddleL, screen);
 +}
 +
 +void PaddleR::show()
 +{
 +    //Show the Paddle
 +    apply_surface(boxR.x, boxR.y, paddleR, screen);
 +}
 +
 +Ball::Ball()
 +{
 +    //Initialize the offsets
 +    collbox.x = SCREEN_WIDTH/2 - BALL_WIDTH/2;
 +    collbox.y = SCREEN_HEIGHT/2 - BALL_HEIGHT/2;
 +    
 +    //Set the square's dimensions
 +    collbox.w = BALL_WIDTH - 5;
 +    collbox.h = BALL_HEIGHT - 5;
 +    
 +    //Initialize the velocity
 +    xVel = 0;
 +    yVel = 0;
 +}
 +
 +void Ball::reset()
 +{
 +    //Reset the offsets
 +    collbox.x = SCREEN_WIDTH/2 - BALL_WIDTH/2;
 +    collbox.y = SCREEN_HEIGHT/2 - BALL_HEIGHT/2;
 +    
 +    //Reset the velocity
 +    xVel = 0;
 +    yVel = 0;
 +}
 +
 +void Ball::handle_input()
 +{
 +    int lORr; //To determine if the ball starts going left or right
 +  
 +    //If a key was pressed 
 +    if( event.type == SDL_KEYDOWN )
 +    {
 +        //Assign random initial velocity
 +        if( event.key.keysym.sym == SDLK_SPACE )
 +        {
 +            lORr = rand()%2;
 +            if(lORr == 0){            
 +                xVel = rand()%5+10;
 +                yVel = rand()%15;
 +            }
 +            if(lORr == 1){
 +                xVel = (rand()%5+10*-1);
 +                yVel = (rand()%15)*-1;
 +            }                
 +        }
 +    }
 +}
 +
 +void Ball::move()
 +{
 +    //Move the ball left or right
 +    collbox.x += xVel;
 +    
 +    //Move the ball up or down
 +    collbox.y += yVel;
 +    
 +    //If the ball went to far up or down
 +    if( (collbox.y<0) || (collbox.y + BALL_HEIGHT > SCREEN_HEIGHT) ) 
 +    {
 +        //Move back
 +        yVel = -1*yVel;
 +    }
 +}
 +
 +void Ball::show()
 +{
 +    //Show the ball
 +    apply_surface(collbox.x, collbox.y, ball, screen);
 +}
 +
 +Timer::Timer()
 +{
 +    //Initialize the variables
 +    startTicks = 0;
 +    pausedTicks = 0;
 +    paused = false;
 +    started = false;
 +}
 +
 +void Timer::start()
 +{
 +    //Start the timer
 +    started = true;
 +    
 +    //Unpause the timer
 +    paused = false;
 +    
 +    //Get the current clock time
 +    startTicks = SDL_GetTicks();
 +}
 +
 +void Timer::stop()
 +{
 +    //Stop the timer
 +    started = false;
 +    
 +    //Unpause the timer
 +    paused = false;
 +}
 +
 +void Timer::pause()
 +{
 +    //If the timer is running and isn't already paused
 +    if( (started == true) && (paused == false) )
 +    {
 +        //Pause the timer
 +        paused == true;
 +        
 +        //Calculate the paused ticks
 +        pausedTicks = SDL_GetTicks() - startTicks;
 +    }
 +}
 +
 +void Timer::unpause()
 +{
 +    //If the timer is paused
 +    if(paused == true)
 +    {
 +        //Unpause the timer
 +        paused = false;
 +        
 +        //Reset the starting ticks
 +        startTicks = SDL_GetTicks() - pausedTicks;
 +        
 +        //Reset the paused ticks
 +        pausedTicks = 0;
 +    }
 +}
 +
 +int Timer::get_ticks()
 +{
 +    //If the timer is running
 +    if(started == true)
 +    {
 +        //If the timer is paused
 +        if(paused == true)
 +        {
 +            //Return the number of ticks when the timer was paused
 +            return pausedTicks;
 +        }
 +        else
 +        {
 +            //Return the current time minus the start time
 +            return SDL_GetTicks() - startTicks;
 +        }
 +    }
 +    
 +    //If the timer isn't running
 +    return 0;
 +}
 +
 +bool Timer::is_started()
 +{
 +    return started;
 +}
 +
 +bool Timer::is_paused()
 +{
 +    return paused;
 +}
 +
 +int main( int argc, char* args[] )
 +{
 +    //The surface for the winning message
 +    SDL_Surface *message = NULL;
 +    
 +    //Quit flag
 +    bool quit = false;
 +    
 +    //The ball that will be used
 +    Ball myBall;
 +    
 +    //The paddles that will be used
 +    PaddleL paddleL;
 +    PaddleR paddleR;
 +    
 +    //The frame rate regulator
 +    Timer fps;
 +    
 +    //Initialize
 +    if(init() == false)
 +    {
 +        return 1;
 +    }
 +    
 +    //Load the files
 +    if(load_files() == false)
 +    {
 +        return 1;
 +    }
 +    
 +    
 +    
 +    //While the user hasn't quit
 +    while( quit == false )
 +    {
 +        //Start the frame timer
 +        fps.start();
 +        
 +        //While there's events to handle
 +        while( SDL_PollEvent(&event) )
 +        {
 +            //Handle events for the ball
 +            myBall.handle_input();
 +            
 +            //Handle events for the paddles
 +            paddleL.handle_input();
 +            paddleR.handle_input();
 +    
 +            //If the user has Xed the window
 +            if (event.type == SDL_QUIT)
 +            {
 +                //Quit the program
 +                quit = true;
 +            }
 +        }
 +
 +        //Move the ball
 +        myBall.move();
 +
 +        //If the ball hits left paddle
 +        if(check_collision(myBall.collbox, paddleL.boxL) == true )
 +        {   
 +            //Bounce ball back
 +            myBall.xVel = rand()%30+15;
 +            //Bounce ball back
 +
 +     if( myBall.yVel == 0 ) {
 + myBall.yVel = 1 ;
 +     }
 +        
 + myBall.yVel = (myBall.yVel/(abs(myBall.yVel)?myBall.yVel:1) )*rand()%20;
 +
 +        }
 +        
 +        //If the ball hits right paddle
 +        if((check_collision(myBall.collbox, paddleR.boxR) == true) )
 +        {   
 +             //Bounce ball back
 +            myBall.xVel = (rand()%30+15)*-1;
 +
 +     if( myBall.yVel == 0 ) {
 + myBall.yVel = 1 ;
 +     }
 +            
 +
 +     myBall.yVel = (myBall.yVel/(abs(myBall.yVel)?myBall.yVel:1) )*rand()%20;
 +
 +        }
 +        
 +        //Move the paddles
 +        paddleL.move();
 +        paddleR.move();
 +                
 +        //Apply the background to the screen
 +        apply_surface(0, 0, background, screen);
 +    
 +        //Show the ball on the screen
 +        myBall.show();
 +        
 +        //If the ball goes off the left side of the screen
 +        if( (myBall.collbox.x + BALL_WIDTH) < 0)
 +        {
 +            //Print a message saying left paddle wins
 +            message = TTF_RenderText_Solid(font, "SCORE BITCH!!", textColor);
 +            
 +            //If a message needs to be displayed
 +            if( message != NULL )
 +            {
 +                //Apply the background to the screen
 +                apply_surface( 0, 0, background, screen );
 +
 +                //Apply the message centered on the screen
 +                apply_surface( ( SCREEN_WIDTH - message->w ) / 2, ( SCREEN_HEIGHT - message->h ) / 2, message, screen );
 +
 +                //Null the surface pointer
 +                message = NULL;
 +            }
 +            
 +            //If space bar is hit then reset the ball
 +            if( event.key.keysym.sym == SDLK_SPACE )
 +            {
 +                myBall.reset();
 +            }           
 +        }
 +        
 +        //If the ball goes off the right side of the screen
 +        if( myBall.collbox.x > SCREEN_WIDTH)
 +        {
 +            //Print a message saying left paddle wins
 +            message = TTF_RenderText_Solid(font, "SCORE BITCH!!", textColor);
 +            
 +            //If a message needs to be displayed
 +            if( message != NULL )
 +            {
 +                //Apply the background to the screen
 +                apply_surface( 0, 0, background, screen );
 +
 +                //Apply the message centered on the screen
 +                apply_surface( ( SCREEN_WIDTH - message->w ) / 2, ( SCREEN_HEIGHT - message->h ) / 2, message, screen );
 +
 +                //Null the surface pointer
 +                message = NULL;
 +            } 
 +            
 +            //If space bar is hit then reset the ball
 +            if( event.key.keysym.sym == SDLK_SPACE )
 +            {
 +                myBall.reset();
 +            }           
 +        }
 +        
 +        //Show the paddles on the screen
 +        paddleL.show();
 +        paddleR.show();
 +        
 +        //Update the screen
 +        if( SDL_Flip( screen ) == -1 )
 +        {
 +            return 1;
 +        }
 +        
 +        //Cap the frame rate
 +        if(fps.get_ticks() < 1000 / FRAMES_PER_SECOND)
 +        {
 +            SDL_Delay( (1000/ FRAMES_PER_SECOND) - fps.get_ticks() );
 +        }
 +    }
 +    
 +    //Clean up
 +    clean_up();
 +    
 +    return 0;
 +}
 +
 +        
 +</code>
 +
 +=====Execution=====
 +Again, if there is associated code with the project, and you haven't already indicated how to run it, provide a sample run of your code:
 +
 +<cli>
 +lab46:~/src/$ g++ -o pong cong2.cpp -lSDL -lSDL_image -lSDL_ttf
 +
 +lab46:~/src/ ./pong
 +</cli>
 +
 +=====Reflection=====
 +This project was really stressing and frustrating at first but after a while I really started to catch on and it was pretty fun!
 +
 +=====References=====
 +In performing this project, the following resources were referenced:
 +
 +  * http://www.lazyfoo.net/SDL_tutorials/
 +  * http://www.cplusplus.com/forum/
 +  * http://www.dreamincode.net/forums/forum/15-c-and-c/
 +  * lair help from matt and other, thanks!!!
 + 
 +