User Tools

Site Tools


user:bkrishe3:portfolio:sysprogproject1

Project: Pong

A project for SysProg by Brett during the 2013 semester.

This project was begun at the beginning of the semester and is anticipated to take X AMOUNT OF TIME. (Upon completion you can correct this with the actual length).

Objectives

  • To build a working pong implementation in C++, with the sdl library

State the purpose of this project. What is the point of this project? What do we hope to accomplish by undertaking it?

Prerequisites

In order to successfully accomplish/perform this project, the listed resources/experiences need to be consulted/achieved:

  • Tutorials from lazyfoo
  • g++
  • resource3
  • Past experience in pong
  • experience2

Background

State the idea or purpose of the project. What are you attempting to pursue?

Upon approval, you'll want to fill this section out with more detailed background information. DO NOT JUST PROVIDE A LINK.

Providing any links to original source material, such as from a project page, is a good idea.

You'll want to give a general overview of what is going to be accomplished (for example, if your project is about installing a web server, do a little write-up on web servers. What is it, why do we need one, how does it work, etc.)

Scope

Give a general overview of your anticipated implementation of the project. Address any areas where you are making upfront assumptions or curtailing potential detail. State the focus you will be taking in implementation.

Attributes

State and justify the attributes you'd like to receive upon successful approval and completion of this project.

  • attribute1: why you feel your pursuit of this project will gain you this attribute
  • attribute2: why you feel your pursuit of this project will gain you this attribute
  • etc…

Procedure

  • Reading the tutorials on the lazyfoo website

The actual steps taken to accomplish the project. Include images, code snippets, command-line excerpts; whatever is useful for intuitively communicating important information for accomplishing the project.

Code

Upon completion of the project, if there is an applicable collection of created code, place a copy of your finished code within <code> </code> blocks here.

//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <stdlib.h>
#include <string>
 
//Screen attributes
const int SCREEN_WIDTH = 1300;
const int SCREEN_HEIGHT = 650;
const int SCREEN_BPP = 32;
 
//The frame rate
const int FRAMES_PER_SECOND = 20;
 
//The attributes of the square
const int SQUARE_WIDTH = 10;
const int SQUARE_HEIGHT = 10;
 
//attributes of the first paddle
const int Paddle_width = 50;
const int Paddle_height = 100;
 
// attributes of the second paddle
const int Paddle2_width = 50;
const int Paddle2_height = 100;
 
//The surfaces
SDL_Surface *square = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *paddle = NULL;
SDL_Surface *paddle2 = NULL;
 
//The event structure
SDL_Event event;
 
//The square
class Square
{
    private:
    //The collision box of the square
    SDL_Rect box;
 
    //The velocity of the square
    int xVel, yVel;
 
    public:
    //Initializes the variables
    Square();
 
    //Takes key presses and adjusts the square's velocity
 	void handle_input();
 
    //Moves the square
    void move();
 
    //Shows the square on the screen
    void show();
};
 
//First Paddle
class Paddle
{
	private:
//	SDL_Rect CP;
 
	int aVel, bVel;
 
	public:
	Paddle();
	SDL_Rect CP;
	void handle_input_p();
	void move_p();
	void show_p();
};	
 
//The Second Paddle
class Paddle2
{
	private:
	//collisionbox
	SDL_Rect CP2;
 
	//Velocity
	int a2Vel, b2Vel;
 
	public:
	//initalize
	Paddle2();
 
	void handle_input_p2();
	void move_p2();
	void show_p2();
};
 
 
//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 )
        {
            //Color key surface
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
        }
    }
 
    //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
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;
 
    //Calculate the sides of rect B
    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;
    }
 
    //Set the window caption
    SDL_WM_SetCaption( "8-bit Pong", NULL );
 
    //If everything initialized fine
    return true;
}
 
bool load_files()
{
    //Load the square image
    square = load_image( "square.bmp" );
	paddle = load_image( "paddle.bmp" );
	paddle2 = load_image( "paddle.bmp" );
 
    //If there was a problem in loading the square
    if( square == NULL )
    {
        return false;
    }
 
    //If everything loaded fine
    return true;
}
 
void clean_up()
{
    //Free the surface
    SDL_FreeSurface( square );
	SDL_FreeSurface( paddle );
	SDL_FreeSurface( paddle2 );
 
    //Quit SDL
    SDL_Quit();
}
 
Square::Square()
{
    //Initialize the offsets
    box.x = 60;
    box.y = 0;
 
    //Set the square's dimentions
    box.w = SQUARE_WIDTH;
    box.h = SQUARE_HEIGHT;
 
    //Initialize the velocity
    xVel = 8;
    yVel = 4;
}
 
Paddle::Paddle()
{
	CP.x = 0;
	CP.y = 0;
 
	CP.w = Paddle_width;
	CP.h = Paddle_height;
 
	aVel = 0;
	bVel = 0;
}
 
Paddle2::Paddle2()
{
	CP2.x = 1250;
	CP2.y = 0;
 
	CP2.w = Paddle2_width;
	CP2.h = Paddle2_height;
 
	a2Vel = 0;
	b2Vel = 0;
}
 
void Square::handle_input()
{
    //If a key was pressed
    if( event.type == SDL_KEYDOWN )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel -= SQUARE_HEIGHT / 2; break;
            case SDLK_DOWN: yVel += SQUARE_HEIGHT / 2; break;
            case SDLK_LEFT: xVel -= SQUARE_WIDTH / 2; break;
            case SDLK_RIGHT: xVel += SQUARE_WIDTH / 2; break;
        }
    }
    //If a key was released
    else if( event.type == SDL_KEYUP )
    {
        //Adjust the velocity
        switch( event.key.keysym.sym )
        {
            case SDLK_UP: yVel += SQUARE_HEIGHT / 2; break;
            case SDLK_DOWN: yVel -= SQUARE_HEIGHT / 2; break;
            case SDLK_LEFT: xVel += SQUARE_WIDTH / 2; break;
            case SDLK_RIGHT: xVel -= SQUARE_WIDTH / 2; break;
        }
    }
}
 
 
void Paddle::handle_input_p()
{
	if( event.type == SDL_KEYDOWN )
	{
		switch( event.key.keysym.sym )
		{
			case SDLK_UP: bVel -= Paddle_height / 2; break;
			case SDLK_DOWN: bVel += Paddle_height / 2; break;
		}
	}
 
	else if( event.type == SDL_KEYUP )
	{
		switch( event.key.keysym.sym )
		{
			case SDLK_UP: bVel += Paddle_height / 2; break;
	 		case SDLK_DOWN: bVel -= Paddle_height / 2; break;
		}
	}
}
 
void Paddle2::handle_input_p2()
{
	if( event.type == SDL_KEYDOWN )
	{
		switch( event.key.keysym.sym )
		{
			case SDLK_LEFT: b2Vel -= Paddle2_height / 2; break;
			case SDLK_RIGHT: b2Vel += Paddle2_height / 2; break;
		}
	}
 
	else if( event.type == SDL_KEYUP )
	{
		switch( event.key.keysym.sym )
		{
			case SDLK_LEFT: b2Vel += Paddle2_height / 2; break;
			case SDLK_RIGHT: b2Vel -= Paddle2_height / 2; break;
		}
	}
}
 
void Square::move()
{
/*
	bool quit;
 
	//If the user has Xed out the window
    if( event.type == SDL_QUIT )
    {
    	//Quit the program
        quit = true;
    }
 
	while( quit == false )
	{
 
		int u;
 
		u = rand() % 5;
 
		xVel = xVel + u;
 
		if( xVel >= 5 )
		{
			xVel = 1;
		}
	}		
*/
 
	srand( time(NULL));
 
    //Move the square left or right
   	box.x += xVel;
 
	//Move the square up or down
	box.y += yVel;
 
	//Square
	//If the square went too far to the left
	if( ( box.x < 0 ) )
	{
		xVel = rand() % 5 + 3;
	}
    //If the square went too far to the right 
    if( ( box.x + 20 > SCREEN_WIDTH ) ) 
    {
       	//Move back
		int u;
 
		u = rand() % 5 + 3;
       	xVel = -u;
    }
    //If the square went too far up 
   	if( ( box.y < 0 ) ) 
    {
    	//Move back
        yVel = rand() % 5 + 3;
    }
	//If the square went too far down
	if( ( box.y + 20 > 650 ) )
	{	
		int w;
 
		w = rand() % 5 + 3;
		yVel = -w;
	}
 
	//Paddle1
	//Collision with paddle on left
//	if( ( box.x == CP.x ) )
//	{
//		xVel = 8;
//	}
 
	//Paddle2
}
 
 
void Paddle::move_p()
{
	//Move the paddle up down
	CP.y += bVel;
 
	if( ( CP.y < 0 ) || ( CP.y + Paddle_height > SCREEN_HEIGHT ) )
	{
	 	CP.y -= bVel;
	}
}
 
void Paddle2::move_p2()
{
	CP2.y += b2Vel;
 
	if( ( CP2.y < 0 ) || ( CP2.y + Paddle2_height > SCREEN_HEIGHT ) )
	{
		CP2.y -= b2Vel;
	}
}
 
void Square::show()
{
    //Show the square
    apply_surface( box.x, box.y, square, screen );
}
 
void Paddle::show_p()
{
	apply_surface( CP.x, CP.y, paddle, screen );
}
 
void Paddle2::show_p2()
{
	apply_surface( CP2.x, CP2.y, paddle2, 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[] )
{
//	SDL_Rect VP;
 
//	VP.x = CP.x;
 
    //Quit flag
    bool quit = false;
 
    //The square
    Square mySquare;
	Paddle paddle;
	Paddle2 paddle2;
 
    //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 square
			//mySquare.handle_input();
			paddle.handle_input_p();
			paddle2.handle_input_p2();
 
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = true;
            }
        }
 
        //Move the square
		mySquare.move();
		paddle.move_p();
		paddle2.move_p2();
 
        //Fill the screen white
        SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );
 
        //Show the square on the screen
	    mySquare.show();
		paddle.show_p();
		paddle2.show_p2();
 
        //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;
}

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:

lab46:~/src/cprog$ ./hello
Hello, World!
lab46:~/src/cprog$ 

Reflection

Comments/thoughts generated through performing the project, observations made, analysis rendered, conclusions wrought. What did you learn from doing this project?

References

In performing this project, the following resources were referenced:

Generally, state where you got informative and useful information to help you accomplish this project when you originally worked on it (from Google, other wiki documents on the Lab46 wiki, etc.)

user/bkrishe3/portfolio/sysprogproject1.txt · Last modified: 2013/05/08 11:22 by bkrishe3