2
\$\begingroup\$

I have the following problem:

I have a a class called Stage, that keeps an list of entities, which it iterates over every update loop, and updates them. One of these entities might be a weapon (PEW PEW!) that when updating spawns new entities (projectiles, KA-ZOOM, KER BANG!). How do I add these new entities to the list in of entities in Stage? Currently, I have Stage as an singleton with global access, so that the entities which in turn spawns entities just calls the instance of Stage's addEntity method, but that feels silly.

Stage -> Entity (weapon) -> Stage again?

I have a similar problem when creating enemies:

Stage -> Entity (enemy wave) -> Stage again

I've been thinking about passing the List into all entities that can create other entities, but then I'd have to change the update method for the base Entity class so that it takes this list, a list which most entities have no need of. Also, when adding an entity to Stage, Stage must be made aware of a number of graphics components for that entity, in order for Stage to be able to tell the renderer (which has an OpenGL context) to load the appropriate resources for those graphic components.

Any ideas what I should do? Am I doing it the wrong way now?

Also, while we're at it, why is Singletons so frowned upon?

\$\endgroup\$
  • 1
    \$\begingroup\$ can you show us some code ? \$\endgroup\$ – concept3d Feb 27 '14 at 11:44
  • \$\begingroup\$ Does stage do any game logic itself or is it just asking each entity to update itself? \$\endgroup\$ – OriginalDaemon Feb 27 '14 at 12:54
  • \$\begingroup\$ Stage updates entities, and is also responsible for collision detection between entities that can collide. \$\endgroup\$ – Herp Feb 28 '14 at 9:26
1
\$\begingroup\$

Add event handling.

There's a ton of different ways you can implement event handling, but the main idea is that different components of your game interact via events, eliminating most cross/circular dependencies. Just as an example, you might have an eventHandler class (can be singleton, if you so wish), which receives and forwards events. All classes would have access to the eventHandler, and would communicate through it.

As for the singleton pattern (or anti-pattern), it's been answered before.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

It looks like your entities should be able to trigger the creation any other type entity.

Option 1: (the case you explained)

public class WolfSpawner extends Entity
{
    public void Update()
    {
        Wolf wolf = new Wolf();
        Stage.Instance.AddEntity(wolf);
    }
}

Option 2: (in this case the Spawner is not aware about the Stage)

public class Spawner extends Entity
{
    protected Vector<ISpawnListener> spawnListeners;

    public void AddSpawnListener(ISpawnListener spawnListener)
    {
        if (spawnListeners == null)
            spawnListeners = new Vector();

        spawnListeners.Add(spawnListener);
    }

    public void RemoveSpawnListener(ISpawnListener spawnListener)
    {
        // ...
    }

    public void Spawn(Entity entity)
    {
        if (spawnListeners != null && !spawnListeners.isEmpty())
        {
            foreach(var spawnListener in spawnListeners)
            {
                spawnListener.Spawned(entity)
            }
        }
    }
}

public class WolfSpawner extends Spawner
{
    public void Update()
    {
        Wolf wolf = new Wolf();
        Spawn(wolf);
    }

}

// Listener interface
public interface ISpawnListener {
    void Spawned(Entity entity);
}

public class Stage implements ISpawnListener
{
    private Vector<Entity> entities;

    public void Spawned(Entity entity)
    {
        AddEntity(entity)
    }

    public void AddEntity(Entity entity)
    {
        entities.Add(entity);

        if(entity instanceof Spawner)
        {
            var spawner = (Spawner)entity;
            spawner.AddSpawnListener(this);
        }
    }

    public void RemoveEntity(Entity entity)
    {
        entities.Remove(entity);

        if(entity instanceof Spawner)
        {
            var spawner = (Spawner)entity;
            spawner.RemoveSpawnListener(this);
        }
    }
}

There are a other options available to tackle this problem.

Singleton is not a bad pattern, the implementation of it is or how you get that single instance is. There are scenarios when you only need a single instance of an object in your application.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I would upvote where it not for the fact that I just created a lol email address some months ago to answer a dudes question, and then stuck to it like an idiot. Maybe I'll create the email account later so I can upvote \$\endgroup\$ – Herp Feb 28 '14 at 9:36
  • \$\begingroup\$ @Herp get to it! :) \$\endgroup\$ – Luis Estrada Feb 28 '14 at 14:10

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.