This is my first game project, coming from a world of scripting and microcontroller programming. This is reasonably different than anything I’ve done before. I need a sanity check, please.
My game is all in 2d. It has a few basic types of objects. Planets, space rocks, missiles, and explosions. I’m using a custom component called “Actor” to store information and set basic behaviors.
For example, if a missile collides with a planet, it should simply be destroyed. If a missile collides with a space rock, it detonates and pushes the rock with a physics force. If a missile collides with a detonation, it should also be pushed, but not detonated. There are a few more basic behaviors but that’s enough for now.
I’m concerned that the way I’m handling these different cases is clunky and over-thought. I’m handling collision events by subscribing to E_PHYSICSBEGINCONTACT2D
, E_PHYSICSUPDATECONTACT2D
, and E_PHYSICSENDCONTACT2D
.
I call a function and pass in eventtype & eventdata, and unpack the roles as follows:
Node* na = static_cast<Node*>(eventData[P_NODEA].GetPtr());
Node* nb = static_cast<Node*>(eventData[P_NODEB].GetPtr());
Actor* aa = na->GetComponent<Actor>();
Actor* ab = nb->GetComponent<Actor>();
Roles ra = aa->get_role();
Roles rb = ab->get_role();
Then I pass them through a matrix of if-statements. This is the part I fear is clunky and over thought. The following example is just two cases, but there are at least 25 of them, and it goes up exponentially if I add more roles. Because in any collision between two different nodes, either one may be A or B, I need two cases for a missile colliding with a rock. (NODEA == missle && NODEB == rock) or (NODEA == rock && NODEB == missile).
Here’s what that looks like:
// Roles are enums.
// There are currently 25 of these if statements to cover all cases
if ((ra == Roles::ROCK) && (rb == Roles::MISSILE))
{
// detonate missile
}
if ((ra == Roles::MISSILE) && (rb == Roles::ROCK))
{
// detonate missile
}
if ((ra == Roles::ROCK) && (rb == Roles::ROCK))
{
// do nothing. The physics engine will handle bouncing.
// There's only a few "Do nothing" cases. I could get rid of them, but it would not trim a lot of fat
}
Of course that could be condensed to only one if statement with a few extra parentheses thrown in there, but I’m just not sure I like this solution. The problem is I can’t see any other effective method. If I add another role, that makes the number of if statements skyrocket because I have N^2 cases. It works, but it seems very…derpy.
Is this a reasonable solution? Would you question my sanity if you saw this in production? Do you have some other ideas? Is there some feature of the engine to facilitate this procedure that I’m not aware of? Should I just shutup and get back to work?