Sign in to follow this  

C++ class design questions

This topic is 2547 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I got some questions regarding how I should design my classes. I'm making a 2D game and untill now I've only had to wory about storing one type of objects, which was platforms. To store the platforms I used a vector in my Level class:


class Level
{
private:
std::vector<Platform*> mPlatformList; // Platforms is a struct

...
public:

...
};





Now when I've completed my editor so it can handle platforms the way I want I need to add other types of objects to the level. So far the platforms only where structs but now I want every object to inherit from the same base class. For that purpose I designed this class:


class Object
{
public:
Object(int x, int y, int width, int height,int ID);
virtual ~Object();

virtual void draw(void);
virtual void update(float dt);

void updateRect(void);

int getX(void) {return mX;};
int getY(void) {return mY;};
int getHeight(void) {return mHeight;};
int getWidth(void) {return mWidth;};
int getID(void) {return mID;};
int getType(void) {return mType;};
int getStatic(void) {return mStatic;}
RECT getRect(void); // dynamicly return the rect!

private:
IDirect3DTexture9* mTexture;
int mX;
int mY;
int mWidth;
int mHeight;
int mID;
ObjectType mType;
bool mStatic;
};




I plan to make objects from this class like platforms, movingplatforms, enemies, ladders, trampolines etc... But what I'm uncertain of is how I should store them all.

1.) Should I use a single std::list<Object*>ObjectList or one list for all different types of Objects?

Some other thoughts:

2.) A Platform doesn't need any more member variables than an Object, but should I still make a new class called Platform to make things clearer?

3.) For the collision detection, should each different object have a
onPlayerCollision(Player *player) function which handles what to do with the player? Or should the Player class check what it collided with and find out by if statements what to do?


Hope I was clear about what I need help with!

Happy Xmas!,
simpler [smile]

Share this post


Link to post
Share on other sites
Should I use a single std::list<Object*>ObjectList or one list for all different types of Objects?

At the minute the class design for Object wouldn't successfully allow you to do, std::list<Object*>ObjectList. I gather you are trying to (either unknowingly or not, to use Polymorphism to allow each object to be update etc through the one list), to do this you need to add some pure virtual functions to the Object class that derived (inherited / child) classes will then overwrite.

This will allow you then to do the following:

std::list<Object*>::iterator ObjectIter = objectList.begin();
for(ObjectIter, ObjectIter != ObjectList.end(); iter++)
{
(*ObjectIter)->update(deltaTime);
}

so your would need to add some functions like this:

virtual void update(float deltaTime) = 0; // = 0 makes it a pure virtual function
virtual void render() = 0;

and this would allow you to use polymorphism, and also declare a list of Object*'s. And then you can do this:

objectList.push_back(new Platform);

Hope that helps!

Share this post


Link to post
Share on other sites
Oh thanks alot!
I didn't remember there were pure virtual functions. What does a virtual function do, I thought it was used for polymorphism as well. What is the big difference?

And yes you are right that I want to use polymorphism. And you think that having a single list of all Objects is the best option?

Share this post


Link to post
Share on other sites
Quote:
Original post by simpler
Oh thanks alot!
I didn't remember there were pure virtual functions. What does a virtual function do, I thought it was used for polymorphism as well. What is the big difference?

And yes you are right that I want to use polymorphism. And you think that having a single list of all Objects is the best option?


pure virtual functions are used in polymorphism:
Polymorphism in C++

they allow derived classes to define their own version of the pure virtual function. So when you do:


Object* pObject = new Platform; // create a pointer of type object and point to a platform object
pObject->Update(deltaTime); // this will run Platform's update, not Object's update.



it will call the Platform's update.

Having a single list of objects (i.e. std::list<Object*> objectList) is a good idea as it allows you to perform a single update and render loop:

std::list<Object*>::iterator ObjectIter = objectList.begin();
for(ObjectIter, ObjectIter != ObjectList.end(); iter++)
{
(*ObjectIter)->update(deltaTime);
(*ObjectIter)->render();
}


and therefore do not have to provide a update / render loop for each object type there is. Plus when creating a level file using an editor, everything is based off Object so when loading in the level everything can be stored in that list.

Obviously as you write more of your game, you may want to create more lists that hold objects, for example, you could have a list that holds only the objects on screen and a list to hold the objects that are offscreen and then you would only need to update and render the onscreen object list.

Play around with it and find an approach that suits your game.

Merry Xmas, and again I hope this helps!

Share this post


Link to post
Share on other sites
Quote:
they allow derived classes to define their own version of the pure virtual function. So when you do:

Object* pObject = new Platform; // create a pointer of type object and point to a platform object
pObject->Update(deltaTime); // this will run Platform's update, not Object's update.

it will call the Platform's update.


I've only used virtual functions in the whole game and they get called the same way you describe, I don't believe that is only for pure virtual functions.

But it seems like a good idea to make the functions pure virtual as the base class Object will be abstract, right?

Do you think I should inherit a class called Platform that wont have any new members? It feels stupid to add a Object to the list when it actually is a platform. But it also feels stupid to make a class w/o any new functions .. :/

Share this post


Link to post
Share on other sites
Hi,
Quote:
1.) Should I use a single std::list<Object*>ObjectList or one list for all different types of Objects?


Having one list for each type of Object is not a good design. You will have to update your level class each time you create a new object class. Instead, do a level class that works with any descendant of Object so you will write the level class once for all.

Nevertheless, a example of separation I do in my game is to handle the objects in a different way according to their behavior (not their type). For example, in my game I have separate lists for objects according to their lifespan. Instances that never move and whose life is as long as the level are in a list (grounds, walls, etc.), instances that can disappear at any time are in a different list (monsters, power-up, etc.)

Quote:
2.) A Platform doesn't need any more member variables than an Object, but should I still make a new class called Platform to make things clearer?


Yes, do it. The reader of your code will then know that the instance behaves like a Platform and you will prepare the place for the Platform-only features you have not thought about yet :)

Quote:
3.) For the collision detection, should each different object have a
onPlayerCollision(Player *player) function which handles what to do with the player? Or should the Player class check what it collided with and find out by if statements what to do?


I had something like onPlayerCollision() in my game but I ended by removing it because it is just one special case of the various types of collisions. Eventually all classes check the instance of the colliding items when necessary in an onCollision(Object& o) function.

By the way, do not make all your virtual functions pure virtual. The virtual keyword is enough for polymorphism and you will want to make them empty functions the day you will create classes that do not have work to do in those functions. Use pure virtual functions only if the base class expects the subclasses to do something. And even then, you will be able to implement the function as empty.

Share this post


Link to post
Share on other sites
Thank you j-jorge for great replies! There's just one thing I didn't grab.

Quote:
I had something like onPlayerCollision() in my game but I ended by removing it because it is just one special case of the various types of collisions. Eventually all classes check the instance of the colliding items when necessary in an onCollision(Object& o) function.


What should have the onCollision(Object &o) function? Isn't all collisions going to be between player-object? Or do you mean that Enemies should check detection as well? Please explain a bit more how your onCollision() function would work if you will [smile]

edit: Should I inherit Player from Object? Don't feel like that, just asking.

Share this post


Link to post
Share on other sites
Quote:
Original post by simpler
Thank you j-jorge for great replies! There's just one thing I didn't grab.

Quote:
I had something like onPlayerCollision() in my game but I ended by removing it because it is just one special case of the various types of collisions. Eventually all classes check the instance of the colliding items when necessary in an onCollision(Object& o) function.


What should have the onCollision(Object &o) function? Isn't all collisions going to be between player-object? Or do you mean that Enemies should check detection as well? Please explain a bit more how your onCollision() function would work if you will [smile]


I would say it depends of your game. For example, if your hero can throw things, like a fireball, then you can have a collision between an enemy and a fireball. In our game we check the type of the colliding item with a dynamic_cast when necessary, which may not be the best solution.

Quote:
edit: Should I inherit Player from Object? Don't feel like that, just asking.


I should say yes. The player lives in the world like any other object, has physic properties, an update procedure and can be rendered. So why not.

Share this post


Link to post
Share on other sites
Quote:
Original post by j-jorge
Quote:
Original post by simpler
Thank you j-jorge for great replies! There's just one thing I didn't grab.

Quote:
I had something like onPlayerCollision() in my game but I ended by removing it because it is just one special case of the various types of collisions. Eventually all classes check the instance of the colliding items when necessary in an onCollision(Object& o) function.


What should have the onCollision(Object &o) function? Isn't all collisions going to be between player-object? Or do you mean that Enemies should check detection as well? Please explain a bit more how your onCollision() function would work if you will [smile]


I would say it depends of your game. For example, if your hero can throw things, like a fireball, then you can have a collision between an enemy and a fireball. In our game we check the type of the colliding item with a dynamic_cast when necessary, which may not be the best solution.

Quote:
edit: Should I inherit Player from Object? Don't feel like that, just asking.


I should say yes. The player lives in the world like any other object, has physic properties, an update procedure and can be rendered. So why not.


Okey I think I will find out how I need to design the collision detection in time.

I've come to a little problem now. I choosed to have one static and one dynamic list of objects. The static objects are supposed to never be deleted untill the game is closed. But in my editor I ofcourse can delete static objects as well. So when I click on a object in my editor right now, it first have to figure out which list the object is in (static or dynamic) and then delete it from there. I maybe should have a combined list of objects in my editor?

Share this post


Link to post
Share on other sites

This topic is 2547 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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