1
\$\begingroup\$

I want to add explosions to my 2D game, but im having a hard time with the architecture. Several game elements might be responsible for explosions, like, lets say, explosive barrels and bullets (and there might be chain reactions with close barrels). The only options i can come up with are:

1 - Having an array of explosions and treat them as a game element as important as any other

Pros: Having a single array which is updated and drawn with all the other game element arrays makes it more organized and simple to update, and the explosive barrels at a first glance would be easy to create, simply by passing the explosion array as a pointer to each explosive barrel constructor

Cons: It might be hard for the bullets to add an explosion to the vector, since bullets are shot by a Weapon class which is located in every mob, so lets say, if i create a new enemy and add it to the enemy array, that enemy will have a weapon and functions to be able to use it, and if i want the weapon (rocket launcher in this case) to have access to the explosions array to be able to add a new one, id have to pass the explosion array as a pointer to the enemy, which would then pass it to the weapon, which would pass it to the bullets (ugly chain). Another problem I can think of is a little more weird: If im checking the collisions between explosions and barrels (so i create a chain reaction) and i detect an explosion colliding with a barrel, if i add a new explosion while im iterating the explosions java will trow an exception. So this is kinda annoying, i cant iterate through the explosions and add a new explosion, i must do it in another way...

The other way which isnt really well thought yet is to just add an explosive component to every element that might explode so that when it dies, it explodes or something, but i dont have good ways on implementing this theory either

Honestly i dont like either the solutions so id like to know how is it usually done by actual game developers, sorry if my problem seems trivial and dumb.

\$\endgroup\$
1
\$\begingroup\$

As far as keeping track of your explosions, a large array is probably great for prototyping something small, but as you're discovering, it doesn't scale well and passing it around can get ugly. Here are a couple of solutions:

  1. Implement an ExplosionManager. Pros: No need to pass around a reference to your explosions array. Easy to group updates of elements it's responsible for. Cons: High coupling between it and the sections of codes that utilize it. Still a rather specific reference to a game element (which brings me to suggestion two...)
  2. Implement a proper scene graph. This is most definitely a larger undertaking than option one. In the case of an explosion, when something in the game creates one, the explosion is parented to it in the graph, automatically allowing it to be rendered. Pros: Explosions (and all other game elements) can be treated generically (think GameObject from Unity). Lower coupling than option one. Cons: Significant amount of work. Sometimes not efficient to scatter updates of like-objects.

As far as creating chain reactions, you could have an explosion query objects in the game environment which are a certain distance away, and communicate to them that there is an explosion happening nearby. The objects react accordingly.

MarkR already provided a good answer for your issues with modifying a list while operating on it. My only suggestion on top of this is to copy the list before operating on it and operate on the copy. It can be a little less confusing than working with 'new' and 'dead' object arrays.

Update: An ExplosionManager would be implemented as a singleton with global access. My Java is rusty, but the resulting code would look something like:

ExplosionManager.addExplosion(new Explosion());

Somewhere in your game's main update loop you have:

ExplosionManager.update(deltaTime);

The class' responsibility is to oversee the existence of every explosion in your game. It holds onto them for their lifetimes, and updates them. Example code and an explanation of the singleton pattern can be found here.

As far as the scene graph is concerned, yes, it's a lot. It comes down to how much of an investment you want to make. If your game is very small and there are no plans to branch it into another project, you don't really need a scene graph. If the game is going to become large though, or you plan on making other games from the architecture of this one, then a scene graph might be a good investment. I could end up writing a lot about scene graphs, so for more information I'll refer you to the Wikipedia page.

\$\endgroup\$
  • \$\begingroup\$ Although your answer seems really helpful, there were a few words I didnt quite understand and if you could help me understand or provide internet sites that u might know that explain them well id appreciate: I didnt understand what is a scene graph in the game dev context and could you provide a little pseudo-code or tips on the ExplosionManager because im having difficulties imagining it, sorry for asking so much of you but you seem very knowledgeable :/ Thank you! \$\endgroup\$ – Xkynar Sep 30 '13 at 10:19
  • \$\begingroup\$ There's also people saying a scene graph might be overkill in stackoverflow.com/questions/5319282/… , id like your comment on it \$\endgroup\$ – Xkynar Sep 30 '13 at 10:23
  • \$\begingroup\$ sorry for shouting but YOU DONT NEED SINGLETONS (for such simple tasks), you need only singletons for caching and maybe logging. Use inverse dependency injection instead of singletons...please world please \$\endgroup\$ – Quonux Oct 13 '13 at 18:39
  • \$\begingroup\$ @Quonux Games lend themselves very well towards the singleton pattern. However, I think it's clear in my answer that utilizing a proper scene graph is the better approach. \$\endgroup\$ – kevintodisco Oct 13 '13 at 21:12
0
\$\begingroup\$

You can use polymorphism to store a "big list of objects". In Java I would normally use an ArrayList for this (although I haven't written any Java for 7 years or something).

So you store an arraylist of objects of your base "game object" class (I normally call mine GameObject, how dull!).

Then you can iterate it and do whatever operations are done on a thing (defined in the base class, can have default implementations which are overridden). So if there is a base class method reactToNearbyExplosion(MyVectorType where) then you can call that on every nearby object, if it ignores it, that's fine.

To avoid the problem of adding to the list while iterating it (the same applies in other languages not just Java), I would normally use another list, "newObjects".

So suppose I have a class ThingManager, and an instance of this keeps track of all my GameObjects, it would have three ArrayLists, which could be called currentThings, newThings and deadThings.

"newThings" are things which are being added in the current frame, and will be moved to currentThings at the end of other processing.

"deadThings" are things which have died recently and not been cleaned up yet (this is sometimes important, particularly in languages which don't have weak references)

I normally implement a method (property?) on my GameObject, "dead" which returns true when it's time for the object to "go away" i.e. be deleted from the game and stop being used for anything. This can be read by the manager to remove it from the currentThings list, but also any other object which wants to know whether something else is dead.

Apologies for the rather extensive rant, but that's how I handle it.

\$\endgroup\$
  • \$\begingroup\$ My main reason to avoid such approach is because i can come up with a few difficulties i would have with it, lets say collision handleing, if i have every object (bullets, enemies, player, explosions...) in the same array, colliding every element with each other in the same way might make it hard to expect different results, lets say, i want the object to get damaged if hit by a bullet but i want solid collision when hit by another object \$\endgroup\$ – Xkynar Sep 29 '13 at 22:12
  • \$\begingroup\$ and in the end id have kind of the some problem would I, i mean i might be thinking it awfuly wrong but in my confused mind, even if I have three arrays, id have to send at least the "newObjects" array as argument to every object capable of creating new objects so i may end up with the train chain of variable passage too :( \$\endgroup\$ – Xkynar Sep 29 '13 at 22:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.