Sign in to follow this  
eektor

Getting started on Pong

Recommended Posts

eektor    182
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?

Share this post


Link to post
Share on other sites
XenocidalFate    156
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.

Share this post


Link to post
Share on other sites
JayeAeotiv    138
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.

Share this post


Link to post
Share on other sites
eektor    182
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?

Share this post


Link to post
Share on other sites
Simian Man    1022
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.

Share this post


Link to post
Share on other sites
eektor    182
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 class
class 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?

Share this post


Link to post
Share on other sites
JayeAeotiv    138
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.

Share this post


Link to post
Share on other sites
eektor    182
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?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this