Getting started on Pong

Started by
8 comments, last by JasonL220 18 years, 5 months ago
I finally did some SDL tutorials and I feel like I'm ready to try my first 2D game, Pong. Well I wanted to ask for some help on it before I get started. First of all I don't want any tutorials on how to make a Pong game, because I want to do this all by myself. (I learn better if I did something without a tutorial stepping me through.) I just want to know how to go about and make the game as modular and OOP as possible for a first game. I do realize months after I will probably look at it and see lots of room for improvement and even wonder what I was thinking then. So can anybody point me in the right direction on what classes to include and how to structure the game? Also should I break up the game into multiple files or just include a header for the main.cpp?
Advertisement
I think something along the lines of

class Paddle{public:     Paddle(string filename); //Load the SDL surface sprite.     void Draw(SDL_Surface *screen);     void SetPos(float x, float y);private:     float m_x,m_y,m_velx,m_vely;     SDL_Surface *sprite;     int m_score;};Paddle* player_one("file.bmp");Paddle* player_two("file.bmp");

would suffice. Then you'd just have to add a ball class and any extra variables you need. Heck, you could probably just add a third Paddle* variable to use as the ball. Granted, I'm not that great of a coder, so there could be a much better way to do it.
You should go ahead and write a basic sprite class.

The paddle and ball can both be sprites. Power-ups can also be sprites.

The sprite class should be able to do the following.

*draw itself to the screen buffer

*animate itself (if needed)

*know its velocity, position

*load in teh sprite image(s) (more than one per frame? or clustered into one image... it depends on how much work you want to do. clustering frames is better)

*have a virtual function we'll call touch() or something similar.
.......

define touch as what should happen if something touches it. Pass the sprite that touches it into this function.

So if ball touches paddle. Ball.touch(const &paddle) paddle.touch(const &Ball) both happen.

Ball.touch could say (bouce based on complex formula to find angle) paddle can do nothing.

Powerup.touch(const &Ball) could say... give player powerup.

Have your collision detection scheme call the touch function appropriately.


This is probably overkill... but if you want OOP then reuse is the idea. I'm thinking about the future when you can make Pong XTREME or something, have all kinds of powerups and such.

--before honor is humility--
Thanks for the suggestions. I like the idea of the sprite class, although all the stuff you mentioned would be a little too complex for a simple game of Pong, but I might as well get started on it and change the class later for other games that need more from the class.

Any other ideas?
I suggest you store the velocity and position as vectors. If you don't know how to use vectors (I mean the math kind, not std::vector), now would be a good time to learn. It may be harder at first, but if you write/get a nice vector class, it will be easier later on.

I also greatly suggest you use time-based movement rather than frame-based.
So I threw some code together to make a basic sprite class. This will be the basic class that I plan on inheriting (I'm not sure how to say that) a ball and a paddle class from this sprite class. Well let me know if it looks alright.

// The sprite classclass Sprite{public:       Sprite(std::string filename, int x, int y, int Vx, int Vy); // Constructor       SDL_Surface *load_image(); // Load and create surface for image       void Draw(SDL_Surface *sprite, SDL_Surface *destination, SDL_Rect *clip = NULL); // Draws the sprite       private:        int m_x = 0;        int m_y = 0;        int m_Vx = 0;        int m_Vy = 0;        std::string m_filename;        SDL_Surface *sprite = NULL;};Sprite::Sprite(std::string filename, int x = 0, int y = 0, int Vx = 0, int Vy = 0){       // Initialize the data       m_filename = filename;       m_x = x;       m_y = y;       m_Vx = Vx;       m_Vy = Vy;}Sprite::load_image(){       // Temporary storage for the image that's loaded       SDL_Surface* loadedImage = NULL;           // The optimized image that will be used       SDL_Surface* optimizedImage = NULL;           // Load the image       loadedImage = IMG_Load(m_filename.c_str());           // If nothing went wrong in loading the image       if(loadedImage != NULL)       {           // Create an optimized image           optimizedImage = SDL_DisplayFormat(loadedImage);                   // Free the old image           SDL_FreeSurface(loadedImage);                   // If the image was optimized just fine           if(optimizedImage != NULL)           {               // Set all pixels of color 0xFFFFFF (white) to be transparent (images should have white background)               SDL_SetColorKey(optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, 0xFFFFFF);           }        }            // Return the optimized image        return optimizedImage;}void Sprite::Draw(SDL_Surface *screen, SDL_Surface *destination, SDL_Rect *clip = NULL){    // Make a temporary rect to hold the offsets    SDL_Rect Offset;        // Give the offsets to the rect    Offset.x = m_x;    Offset.y = m_y;        // Blit the surface    SDL_BlitSurface( sprite, clip, destination, &Offset );}


As for storing the position and velocity as vectors, is it alright just separating it into the components like I did in the sprite class? What do you mean by making a vector class?

I like your idea of making the movement based on time instead of frame based. I will remember to put that in. I plan on capping the frame rate but if I make I make the movement time based, I would not have to worry about capping the frame rate?
Sprite(std::string filename, int x, int y, int Vx, int Vy); // Constructor

I would recommend using...

Sprite(const std::string &filename, int x, int y, int Vx, int Vy); // Constructor

It'll reduce some of the overhead of creating another string for the parameter. For pong which won't be creating tons of sprites, it's not a big deal at all. I just try to encourage simple optimizations, making them a habit comes in handy for the future.

A vector class should be able to store x, y, and z coordnates. They can represent any unit type that is a vector. You should be able to multiply vectors against eachother, find dot products, etc.

A vector is a magnatude in a given direction. For example. 300m/s @ 30 degrees.
If you want to add 20 m/s @ 10degrees and 40 m/s @40 degrees, how do you do that? There are several ways and the easiest (algebra) isn't fresh on my mind. You can also draw them with a protractor and then concat them together. Draw a line between them and bam, you have the addition.

A class does this for you. Though an understanding of the mathematics does help, it is by no means required (the beauty of abstraction).

Here's a half decent site to show you vector addition with the graphical method: http://www.glenbrook.k12.il.us/gbssci/phys/Class/vectors/u3l1b.html

There's much more to vectors than addition, though this is definately a starting place.

--before honor is humility--
Thanks for the tip.

As for vectors I understand them pretty well. (I studied engineering.) Although since I'm not using them at all now (studying business now) I'm forgetting it. Are you saying its easier to record the vector as a magnitude and its angle? I preferred recording the vector by breaking it up into its x,y, and z components as its easier to add, subtract the vectors. Although when working on collisions between the ball and the paddle I might have take in consideration the angle, if I want to make the pong game similar to breakout.

Oh and to break up the vector in its components its |magnitude|*cos(angle) and |magnitude|*sin(angle) I have never used the cos and sin in a program but I'm guessing they are in math.h right?
I would store them x, y, z in the classes. I didn't know if you had an understanding of vectors. they are easier to conceptualize with angles.

--before honor is humility--
I've got my pong code if you want a look (it's allegro though)

This topic is closed to new replies.

Advertisement