======Project: PONG====== Honestly Casey has to help me a great deal to make this. I give a big thanks to him. =====Objectives===== State the purpose of this project. What is the point of this project? What do we hope to accomplish by undertaking it? =====Prerequisites===== http://www.lazyfoo.net/SDL_tutorials/ Of Course CASEY, I think he may be annoyed how many times I bugged him. =====Background===== Old games lol =====Code===== /*Pong Clone using C++ and SDL libraries*/ //The headers #include"SDL/SDL.h" #include"SDL/SDL_image.h" #include"SDL/SDL_ttf.h" #include #include #include //The screen attributes const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 475; 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 collision box for the left paddle //SDL_Rect boxL; //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("Move the Ball", NULL); //If everything initialized fine return true; } bool load_files() { //Load the images ball = load_image("Ball.bmp"); background = load_image("Background.bmp"); paddleL = load_image("paddleLeft.bmp"); paddleR = load_image("paddleRight.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_w: yVel -= PADDLE_HEIGHT/9; break; case SDLK_s: 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_w: yVel += PADDLE_HEIGHT/9; break; case SDLK_s: 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 if( myball.yVel == 0 ){ myball.yVel = 1; } myBall.xVel = rand()%30+15; myBall.yVel = (myBall.yVel/abs(myBall.yVel) )*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; myBall.yVel = (myBall.yVel/abs(myBall.yVel) )*rand()%20; if( myball.yVel == 0 ){ myball.yVel = 1; } } //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, "BLUE WINS!!", 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, "RED WINS!!", 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; } =====Reflection===== There is a lot to do just to create a game. I am definitely not a game person.