0
\$\begingroup\$

Im having a hard time figuring out a solution to a problem that seems it should be easy to answer but since i cant come up with a good solution I bid your knowledge:

In my game i have a state manager which deals with either the game is at the menu state, level1 state, level2 state, etc etc, every different screen condition is a state that is, and in my level state i created a base level class so i can extend the level1, level2, etc levels.

In the base level class, it is where i declare my common level variables, like Player, the Tilemap, the array of enemies (mobs), the CollisionManager etc. (this might be what i am doing wrong...) and i wanna add explosions to the game, which will occur at least when i shoot explosive barrels (and the barrels really arent the problem because since they are created in the beggining of the level, i can just add an array of barrels and set the argument of the barrel to receive the array of explosions pointer so the barrel just adds a new explosion when the time comes) and when explosive bullets hit the wall.

Now my problem is specially the bullets, because explosive bullets are created by the mobs which might use a rocket launcher (including the player) and i dont really think sending the array of explosions to every mob that might shoot explosive bullets is good architecture, so my question is how i solve this problem or even better how i improve my architecture in a whole to avoid problems like these.

P.S. As a side note regarding how the mobs shoot bullets, every mob has a Weapon, which is a class that extends in the several weapons the game might have, from pistols to lasers and flamethrowers, which are all functional and working lovely. This means, though, that if id send the explosions array to the mob that will use rocket launcher, i would then have to send that pointer to the weapon, and from weapon to every bullet that the weapon spawns, so the bullets are the ones adding the explosions to the array when the time comes. This train-like passing of the array is what is bugging me and what i strive for a solution.

P.S.S. Although every advice is very appreciated, answers telling me to use Aggregation of Components Architecture are, at the moment, "ignored" because im trying to correctly use the traditional Hierarchical approach for this game, i might use component architecture in a future game though, it seems pretty neat : )

\$\endgroup\$
2
  • \$\begingroup\$ For what reason do you want to aggregate all your explosion instances in one array? \$\endgroup\$ Sep 29, 2013 at 6:19
  • \$\begingroup\$ I thought treating them as separate individual objects would be easier to handle their existance and collision with the other objects \$\endgroup\$
    – Xkynar
    Sep 29, 2013 at 19:57

2 Answers 2

1
\$\begingroup\$

Use factories and messages. The weapon does not need to directly insert a bullet into an array. It need only send out a message saying "Create bullet type Explosive at position X,Y going in direction U,V with speed S" and then a message handler on a factory system can listen for the CreateObject message and then spawn the correct type of object with the correct parameters.

This completely decouples the need for any individual object to know how other objects are stored, managed, etc. It allows more genericism as you can now use strings, enums, or external data to denote the type of object to create rather than needing to explicitly instantiate one.

The problem has nothing to do with using hierarchies of types or components. It has to do with the tight coupling you're creating between object types, behaviors like gun firing, and the lack of messaging or abstract factories. All that the weapon needs to know is a general idea of what it fires and which position and velocity to spawn it at. The actual spawning of the object can and should happen elsewhere.

This can even be fully data-defined. You can make your Bullet class have a field that denotes what type of explosion it spawns, Weapon can define which Bullet it fires, etc. Then you can trivially create a new weapon that fires a slow-moving green bullet that explodes in a rain of acid or some such. Not need to recode, no need to recompile. Easy to mod, easy to update in a nice designer-friendly tool, etc. Yes, components make this even easier, but the really important part is the data-driven design.

\$\endgroup\$
3
  • \$\begingroup\$ I find the logic behind the "messaging and handlers" very simple to understand, but not that simple to put in practice, since i cant find good examples. Ive been trying to understand the observer pattern with a few examples but even using that method to check for the bullet message, so that the observer can act (i guess this is kind of what u mean), to make the bullet an observed subject, it needs to be added to the observer's list, and for that it needs access to the observer, so in the end i still need access to "far away" objects... \$\endgroup\$
    – Xkynar
    Oct 3, 2013 at 23:50
  • \$\begingroup\$ You don't necessarily need to make your observers on individual objects. A single central message queue works just fine. Look up "pub-sub" as this observer pattern is better known. It may not be the most efficient method around, but somehow I doubt you're writing Battlefield 5 and in need of "absolute most fastest ever." \$\endgroup\$ Oct 3, 2013 at 23:57
  • \$\begingroup\$ Thanks, Ill search for it, it sounds interesting although most of the examples i can find are of client-server which makes it a little harder to understand the basis, but the logic is very interesting \$\endgroup\$
    – Xkynar
    Oct 4, 2013 at 10:26
0
\$\begingroup\$

Small nitpick: you say "array of explosions" but I'd rather that be encapsulated in an ExplosionManager.

So your bullets need to create explosions, but you don't like passing the ExplosionManager from mob to weapon to bullet ("train-like passing").

How about making ExplosionManager a globally-accessible singleton? Of course we can google "why are globals bad?" and "dependency injection" to learn why this isn't ideal, but I mention it anyway.

How about if the Bullet class has a static pointer to an ExplosionManager? You could set this pointer in one place in code (so you don't have to pass an ExplosionManager to every Bullet instance).

How about a bullet just does "new Explosion()" and each Explosion is responsible for adding itself to the manager/array? This just shifts the problem from Bullet to Explosion so it's not really a solution. However, I kinda like it because the fact that Explosions are kept in a big array seems like an implementation detail that users of the Explosion class shouldn't have to care about.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .