1
\$\begingroup\$

My goal is to check collisions among the actors that are in the Stage.

My question is: is it necessary to maintain a list for each type of actor I have?

Doing that I get 3 problems, 2 bad design problems and 1 exception.

Design problems I don't like:

  1. The Actors used by the player add bullets (another Actor) to the stage. I need to pass my Stage to these Actors as argument in order to add a bullet to the list of bullets, that is held by the Stage.

  2. Each time I need to add an Actor to the Stage, I have to perform 2 add operations, one in the list and one directly to the Stage.

  3. If I check collisions iterating over the lists and I find out that an enemy (another actor) is dead, I need to remove the enemy both from the stage and from the list, but I can't remove it from the list because I get "Concurrent modification exception".

Is there some common design technique to handle this stuff?

\$\endgroup\$
  • \$\begingroup\$ My recommendation would be to use Box2D, even to check simple collisions, even if you don't care about physics. When I read your question, I see me a couple of month ago struggling, like you are right now, on collision problems. And I always though "Naaaah, I won't waste time learning Box2D, for such a simple project". Actually it is worth spending time learning Box2D. You won't face collision problems anymore. And actually Box2D is quite simple to use, when you know it. \$\endgroup\$ – vdlmrc Nov 11 '15 at 18:17
  • \$\begingroup\$ I solved my problem for now. I keep 2 kind of lists, one in which i add the actors to be checked, and one in which i add the actors to be removed. \$\endgroup\$ – Loris Nov 13 '15 at 9:59
0
\$\begingroup\$

While not necessarily the best solution, this is how I have overcome these problems with my game engine

  1. I personally don't have a problem with passing the Stage to an Actor. Also, if the parent actor is already part of a stage you can also get the stage by calling

    Actor.getStage()

    For your physics engine, I suggest that instead of having a list represent your physics engine, you should create a physics engine class that handles the registration/deregistration of physics objects. This way, you can have it act as a gateway so that the list doesn't get modified directly by an actor.

    If you really don't like passing in your stage and physics engine to every actor, an alternative is to implement some sort of messaging system where the Actor creating the projectile sends a message saying, "Hey! I created a projectile and here it is" and then have your physics engine and stage register to receive these messages so they can add the projectile accordingly. This can be done via static message handler classes or with the observer pattern.

  2. You have to let both your physics engine and stage know that a new actor was created somehow. I understand the desire to make them work off of the same list, but it is likely that you will want some Actors that are drawn by the stage that aren't participating in the physics engine (like a hud). Even though you are doing two adds, you are adding the same object to both lists and thus not increasing your memory footprint.

  3. This is a limitation of Java. It really doesn't like you messing with a collection while you're iterating over it.

    During my collision detection in the physics engine, if an Actor dies, I don't remove it right then. Instead, I mark a flag on the actor that it is dead. Then, the first step of my physics engine the next time around (before collision detection), is to go through my list and get rid of all of the dead actors. That way, you aren't modifying the physics list while you are looping through it and detecting collisions.

    Sadly, there isn't a really elegant way to loop through a list while removing its objects in java. The usually approach is to either loop through a copy of the list while removing from the real list or to keep a list of objects to be removed and then loop over it, removing the objects from the real list.

\$\endgroup\$

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.