I have a 2d physics engine that I've been programming in C++ using SFML; I've implemented a rough collision detection system for all SandboxObject
s (the base class for every type of physics object), but I have a dilemma.
I plan to have many different derived classes of SandboxObject
s, such as Circle
s, Rect
s, and so on, but I want a way to check if the roughHitbox
of each SandboxObject
collides with another.
When the program starts, it allocates memory for, let's say, 10,000 Circles
int circleCount = 0;//the number of active Circles
constexpr int m_maxNumberOfCircles = 10000;//the greatest number of circles able to be set active
Circle* m_circles = new Circle[m_maxNumberOfCircles];//create an array of circles that aren't active by default
like so.
and every time the user 'spawns' a new Circle
, the code runs
(m_circles + circleCount)->setActive();`
circleCount++
Circle
s that aren't alive essentially do not exist at all; they might have positions and radii, but that info will never be used if that Circle
is not active.
Given all this, what I want to do is to loop over all the different arrays of derived classes of SandboxObject
because SandboxObject
is the base class which implements the rough hitbox stuff, but because there will be many different derived classes, I don't know the best way to go about it.
One approach I did try (with little success) was to have a pointer to a SandboxObject
SandboxObject* m_primaryObjectPointer = nullptr;
this pointer would be null unless there were > 1 SandboxObject
s active; with it, I tried using increment and decrement functions that checked if it could point to the next SandboxObject
, but I couldn't get that to work properly because a base class pointer to a derived class acts funky. :/
I'm not looking for exact code implementations, just a proven method for working with the base class of many different derived classes.
Let me know if there's anything I should edit in this question or if there's any more info I could provide.
Your problems are caused by your desire to use a polymorphic approach on non-polymorphic containers.
The advantage of a SandboxObject* m_primaryObjectPointer
is that it allows you to treat your objects polymorphicaly: m_primaryObjectPointer -> roughtHitBox()
will work regardless of the object's real type being Circle
, Rectangle
, or a Decagon
.
But iterating using m_primaryObjectPointer++
will not work as you expect: this iteration assumes that you iterate over contiguous objects in an array of SandboxObject
elements (i.e. the compiler will use the base type's memory layout to compute the next address).
Instead, you may consider iterating over a vector (or an array if you really want to deal with extra memory management hassle) of pointers.
vector<SandboxObject*> universe;
populate(universe);
for (auto object:unviverse) {
if (object->isActive()) {
auto hb = object -> roughtHitBox();
// do something with that hitbox
}
}
Now managing the objects in the universe can be painful as well. You may therefore consider using smart pointers instead:
vector<shared_ptr<SandboxObject>> universe;
(little demo)