I've decided to make my next game using my own simple engine. I've already written some code for object rendering, physics etc. and now I'm thinking about how to easily connect them together.
I want to make hierarchic structure with one master object, lets call it Scene which will have parent as Sprites or InteractiveObjects and every Sprite or InteractiveObject could have its own child which would have its own child.. I think you already got my point here :)
Let's assume, that every object type will inherit from some base object, let's call it Node for example. I'm not sure yet, if Node will be "real" object which will have its size, position etc. or only abstract wrapper for every object in game (I tend to option two actually).
And finally. My goal is, to have object of actual Scene, call something like Scene->Move(x,y) and it will move every child of Scene (or Sprite, InteractiveObject etc.). Or Scene->Render() and it will render every (renderable) child. If I create Sprite, I want to add child like Sprite->addChild() and child could be another Sprite, InteractiveObject or just simple Node.
And now my question. What's the best way to implement it with C++? Or am I totally wrong and this structure is stupid? :)
I should think that whether or not the structure is sensible depends somewhat on what you really want to achieve -- the system sounds very flexible, but usually there's a trade-off between flexibility and performance. Depending on the genre of the game, performance may be hard enough to come by.
Also, if all things derive from some BaseNode, they all need (although possibly empty) methods for all kinds of things whether or not they actually can be rendered, moved etc. Or you'd end up with lots of dynamic_casts, which isn't very nice either. It might therefore be better to have slightly less flexibility and differentiate between game entities and graphical entities, with the latter being part of the former (you might want to allow a game entity to be made up from multiple graphical entities, or sub-entities, though).
If you do go with your current architecture, I should think that each BaseObject has something like a vector and when you call, say, render() on a master object, it goes through all it's children and calls render on them. They do the same and do any render code that is appropriate to them.
Another question is, though, whether an object could feasibly be attached to several other objects (if there is a difference between rendering and physics, for example). If so, it can get hairy to know when to delete an object, unless you don't use plain BaseObject*, but some form of auto_ptr or shared_ptr.
I hope that this answer does help you a little, though I realise it's not a simple "this is they way!" one.
Related
Say I want to create a list of variables/objects to store something very specific(say the coordinate for where an enemy needs to spawn in a videogame), at first I would only need a simple point in space to store this information but later on I may want to add the enemy type and other data specific to each element of this list. Is it good practice to write a whole new class or struct with only just the initial data member I need in hopes that whenever I need to update the list with more data per element I can just add members to this previously redundant struct/class? Furthermore, is packaging an already existing type into a new one in the spirit of being more descriptive something that actually helps code readability?
Sounds like a classic case for some good old object orientated programming.
So the idea would basically be that you have your simple struct/class with, as mentioned in your example, coordinates. If you would want to add another enemy with some extra attributes to be stored you would go ahead and create a new class/struct that inherits from the very basic class. That way you get all the attributes the basic class had in your new class plus you can define new ones.
That way you have a good structure in your code and it is easy to understand what is going on. Scalability and reusability also profit greatly from this, which is why this concept is state-of-the-art.
This might sound a little confusing at first, but I recommend to read up on inheritance and object oriented programming in general. I promise it is not too hard once you get used to the thinking patterns.
I have a collection of objects, lets say QVector<ApplicationStates>, which registers the most important operations done in my software. Basically, this object is meant to process redo/undo operations.The application is built using a lot of delegated objects. Operations which have to be registered lie in a lot of these objects. As such, I am always passing my collection of objects, in each delegate under the form:
class AWidget : public QWidget{
AWidget(QVector<ApplicationStates>* states, QWidget* parent = nullptr);
...
It seems ugly to me. I think about two solutions:
Singleton;
Simply declare the QVector as a static global variable (I read that global variables are evil).
Does someone have a suggestion?
Thanks for your answers.
I get into a similar situation from time to time, and I have found simply wrapping your vector in a class called something like "ApplicationContext" then passing a shared pointer or reference to an instance of that around saves the day. It has many benefits:
You avoid the global / singleton, and you are free to in fact have several instances concurrently in the future
If you suddenly have more than just that vector of objects that you need to pass arround, simply extend your context class to add whatever you need
If your vector suddenly becomes a map or changes in other ways, you need not change any interfaces that pass it along such as the signals/slots. (You will need to change the implementation where the vector is used of course).
BONUS: The code becomes easily testable! You can now make test cases for this class.
This might not be the best solution in all cases, but I think it comes pretty close in this case!
I am designing a game engine in c++. I am currently working on categorizing the different entities in the game. My base class is SpriteObject that two classes MovableObject and FixedObject inherit from. Now if i for example create an instance of a MovableObject and want to add it to a Vector of Sprite and a Vector of MovableObject i just do:
Vector<Sprite*> sprites;
Vector<MovableObject*> movableObjects;
MovableObject* movingObject = new MovableObject();
sprites.push_back(movingObject);
movableObjects.push_back(movingObject);
But as the different categories and entities grow the code will get large (and it would get tiresome to add every entity to every vector that it belongs to). How do i automatically add an object to the vector that it belongs to when it is created?
EDIT 1: I think i just came up with a solution, what if i just make a global static class Entities that holds all the vector of entities in the scene. Every entity could have access to this class and when a entity is created it just adds a pointer version of itself to the corresponding vector(s) in that global class.
EDIT 2: But i forgot that my solution requires me to still manually add every entity to its matching vector. I just split the work among the different entities.
This is a nice problem.
I think that I would implement it like this: There will be an addToVector() method in Sprite class, and each derived class will override it to add itself to the corresponding vector.
I would suggest a different approach. But before I start I would like to note one thing with your current design.
I would hide the creation of those objects behind a facade. Call it a scene or whatever. Using new manually is bad from a couple of perspectives. First of all if you decide you want to change the scheme on how you allocate/construct your objects you have to change it everywhere in the code. If you have a lets say a factory like Scene you just change the implementation and the calls to scene->CreateObject<Sprite>() will remain the same everywhere else. This might get important once you start adding stuff like custom memory allocation schemes, object pools etc and at some point you will if you will start to grow your engine. Even if this is just an excercise and a for fun project we all want to do this like its actually done, right ;) ?
Now going back to the core - dont abuse inheritance.
MovableObject is not a Sprite. Static Object is not a sprite either. They are that, movable and static elements.
A sprite can be movable or static, so it has a behavior of a dynamic or static element.
Use composition instead. Make a Sprite accepting behavior, or better a list of behaviors. In fact the Sprite itself is just a behavior on a Game object too, it just controls the way it is presented to the user.
What if you had an object that can be attached multiple behaviors like the fact it is a dynamic one, it has a sprite presence on the scene and even more is a sound emitter!
If you add those behaviors to the object you have to create them first. They can, when constructed, decide to which list they should subscribe to.
This is all metaphors for actually a well known system, that is proven to work well and is actually used in most game engines nowadays. Its a Entity Component System.
You object with behaviors are Entities, Components are those Behaviors and each of them is controlled by one system that knows the component and knows how to update/handle them.
Objects in the scene are merely a set of components attached to them that act upon them.
I always run into confusion with who should know about the other.
for example:
Circle.Draw(&canvas) or Canvas.Draw(&circle)
or Draw(&canvas, &circle)
EmployeeVector.Save(&file) or File.Save(&employee_vector)
or even still
void operator() (Employee e) { Save( e.Serialize();}
for_each(employees.begin(), employees.end(),File)
I think I end up "abstracting" too much where I have all kinds of adapters so nobody knows about anybody.
Depends on who has the expertise.
If the only thing you can draw are circles, then of course you could just put that in Canvas and be on your way. If Canvas has a method to draw generic Shapes, then it falls on the various subclasses of Shape to draw themselves. For instance, a circle surely knows how to draw itself on a canvas. I doubt a canvas knows natively how to draw a circle, unless you hardcode the functionality, which kinda kills the whole idea of polymorphism.
For the same reasons, a vector would probably know how to save itself to a file, but I doubt a file knows what to do with a vector. But a vector can contain a variety of things, so it should delegate most of the work to its actual elements. So the for_each idea is probably the best.
Like most design questions, the answer is, it depends. :-)
Is it meaningful for something to know how to draw itself? possibly. It's also equally possibly that something else knows how to draw it. If the object is a graphical entity, it probably should know how to draw itself.
As for things like saving, again, it depends... it can be good for things to know how to serialize themselves to an abstraction like a stream, but also, sometimes, it's better not to couple entities to such trivial matters like serialization....
For classes that you are creating, you usually make them do work involving themselves. A Circle will draw itself onto a Canvas, so will a Rectangle. That way, if they are all subclasses of Shape, they can draw themselves through a Shape interface. It is the same for saving. This is extensible -- you do not need to guess all the possible shapes when designing the Canvas class.
For the "it depends" cases, for me, it usually involves utility methods for classes already defined by some library. For example, save/load commonly used STL data structures like map, set, vector, etc; via a File utility class with static methods.
I have a data structure that stores ... well, data. Now, I need to access various pieces of data in slightly different manner, so I'm essentially building an in-memory index. But I'm wondering: should the index hold pointers or copies?
To elaborate, say I have
class Widget
{
// Ways to access the list of gears...
private:
std::list<Gears> m_gears;
};
Now, I have two Widgets, and there exists between these two a mapping between their Gears. Currently, this is
boost::unordered_map<Gear, Gear>
but Gear is a fairly hefty class, and I feel like making so many copies is poor design. I could store a pointer, but then the mapping is only valid for the lifetime of the corresponding Widgets, and you start getting ->s... (And if that std::list ever changes to a std::vector, it gets more complex...)
Pertaining to the copies, it's actually slightly worse: There's two boost::unordered_maps, one for each direction. So, for each Gear, I'm making up to 2 copies of it.
Alternatively, I could put the index inside the Widget class, but I feel like this violates the responsibilities of the Widget class.
You might try Boost Pointer Container Library: http://www.boost.org/doc/libs/1_43_0/libs/ptr_container/doc/ptr_container.html
I think it addresses exactly the problem you are facing.
Could you store all gears in one place, like statically in the gears class, and then have each mapping AND widget store only the reference/index to it?
You would have to keep track of references to each gear so you know when you can dispose them, but that should be easy enough.