0

I'm trying to program a game-simulator in Java using OOP (SC2 to be precise). Basically the games has units (each different unit is a class, each actually created unit is an instance of that class), and has buildings with different roles. Again buildings each have their own class, and when a building is built its class is instantiated. So I'll have u1, u2, u3, b1, b2 b3... etc instances.

All fine for that.

Now, I need to simulate time increment. I know that eventually I need the user to be able to interact with the game (e.g. at key times, that are game-dependant and NOT know before the simulation, I want user-input). This means I will want the game to run for X time increments, then possibly stops for a specific event (when Y resources have been obtained, which allows to create a building/unit, or when a new building has been created and opens up new decisions).

So to sum up here are my (general) classes:

class Unit extends GameElement{
  //bunch of attributes
  //bunch of units-specific methods, getters & not relevent here

   public void timeIncrement () {
     //Manages all time-dependant changes for this unit when
     //that method is called
    }
        }

Similarly for building, they will have their own timeIncrement methods, which will manage their own (class-specific) time-dependant behaviours.

Both building classes & unit classes are extension of:

abstract class GameElement {

//Manages time-dependant behaviours
public abstract void timeIncrement();

//Manages the building/creation of the game element
public abstract void building();
}

which defines common methods needed ,e.g. each unit must manage it's time and also its building procedure.

I have problems as to how to define

class TimeManagement{
    //Those ArrayList list all objects created with a 
    //timeIncrement() method that needs to be called
    private ArrayList<Units> = new ArrayList<Units>();
    private ArrayList<Buildings> = new ArrayList<Buildings>();
    //This is the (universal game-wide) timestep. It might change so I
    //need to have a single-place to edit it, e.g. global variable
    private double TIME_STEP = 0.5;

}

Basically my plan is to have TimeManagement with ArrayList of all the objects it needs to tell that the time has incremented. For each arrayList, it will loop through the objects it contains and call myObject.timeIncrement() method, and then the objects will management he increment however they are programmed to.

My problem is how to define this TimeManagement class. It doesn't make sense to me to instantiate this class. But if I declare it static I can't (unless I am wrong on this - I haven't used static classes very much yet) update it's ArrayList when I build new units, so how will TimeManagement be able to call the timeIncrement for all the object that needs it?

Or should I just create a bogus instance of TimeManagement, so I don't have to declare it static? But this just feels wrong, from a programming point of view.

I would prefer to work something out with this general architecture. It seems to me that it requires something along the lines of this TimeManagement class but I just can't quite put my finger on it it seems....

logicOnAbstractions
  • 2,178
  • 4
  • 25
  • 37
  • Why would be a "bogus" instance? I think it would be a perfectly valid one. BTW you can also declare everything static in the class. It is arguable which is the correct one. – meskobalazs Feb 23 '15 at 16:32
  • Another note: constants are usually static fields. – meskobalazs Feb 23 '15 at 16:35
  • So if I declare everything static in the class (e.g. including the ArrayLIst I guess?) I should be able to add element to those arraylist even though my class is static? – logicOnAbstractions Feb 23 '15 at 16:36
  • Yes. Just remember you are basically using global variables. – meskobalazs Feb 23 '15 at 16:41
  • Ok, yes I get it now: basically create a public final class TimeManagement, set all attributes & methods in it static and then I can just reference that TimeManagement class when I need to (instead of reference to an instantiation of it). If you want to write up an structured answer you can, otherwise I might do it later if you don't want to. – logicOnAbstractions Feb 23 '15 at 16:59

1 Answers1

1

The quick way

You can just simply make all fields static:

class TimeManagement {
    private static List<Unit> = new ArrayList<Unit>();
    private static List<Building> = new ArrayList<Building>();

    private static final double TIME_STEP = 0.5;
}

This way, you need to refer to TimeManagement statically all the time.

Using the Singleton pattern

However, in this case, I would rather use a singleton instead:

class TimeManagement {
    private static final double TIME_STEP = 0.5;
    
    private List<Unit> = new ArrayList<Unit>();
    private List<Building> = new ArrayList<Building>();

    private TimeManagement instance;

    public static TimeManagement getInstance() {
        if (instance == null) {
            instance = new TimeManagement();
        }
        return instance;
    }
}

This way you would get the one existing instance by calling the #getInstance() method. One further note to the code: I kept the TIME_STEP variable static, as for constants, it makes sense, as they are inherently bound to the class, and not specific instances.

Community
  • 1
  • 1
meskobalazs
  • 15,741
  • 2
  • 40
  • 63
  • 1
    Here, the singleton is certainly better (see [singleton vs static methods](http://javarevisited.blogspot.fr/2013/03/difference-between-singleton-pattern-vs-static-class-java.html)). If the environment is multi-thread, the singleton has to be adapted for thread safety (see [singleton thread-safe](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java)). In this use case, multi-thread may make sens to allow the scheduler to update the model _in parallel_ with user interaction. Then `Unit`, `GameElement`, etc. should be made thread-safe too. – T.Gounelle Feb 23 '15 at 18:54
  • Thanks Abbé for the links (singlet vs static). I didn't know about Singleton and that background was definitely useful. I didn't know about Singleton pattern, that's definitely a good tool to have, thanks for the tip will do well! – logicOnAbstractions Feb 23 '15 at 19:52