Chapter 23. The Singleton Pattern, Java HashMap, Storing Bitmaps Efficiently and Designing Levels

This is going to be a very busy and varied chapter. We will learn the theory of the Singleton design pattern.

We will be introduced to another of the classes of the Java Collections, HashMap in which we will see how we can more efficiently store and make available the wide variety of bitmaps that are required for this project. We will also get started on our new and improved Transform class, code the first of the component-based classes, code the all-new Camera class and make a significant start on some of the more familiar classes, GameState, PhysicsEngine, Renderer, GameEngine and more besides.

Here is a list of what to expect and the order to expect it.

  • The Singleton pattern
  • The Java HashMap class
  • The memory problem and the BitmapStore
  • Coding a basic Transform
  • Coding the block-based component classes
  • Creating the game levels
  • Coding a stripped-down GameObjectFactory
  • Coding the GameState
  • Coding the SoundEngine
  • Coding the PhysicsEngine
  • Coding the Renderer
  • Explaining and coding the Camera class
  • Coding the HUD
  • Coding the UIController
  • Coding the Activity
  • Coding the GameEngine
  • Coding a stripped-down LevelManger
  • Running the game for the first time

By the end of this chapter we will see the game in its first runnable state!

Tip

Throughout the course of this chapter there will be loads of errors in Android Studio because so many of the classes are interconnected and we can't code them all simultaneously. Note also that when there is an error in an interface file (and there will be) attempting to implement that interface will also cause an error in the implementing class. Stick with it until the end of this chapter as it all comes together, and we will see the first results on our screens. Be sure to read the information box at the top of chapter 22 as well as the one below for the quicker copy and paste approach you might like to take.

If you want to copy and paste the code read this next information box.

Note

Feel free to copy and paste these classes if you prefer. All classes go in the usual folder except where I specifically point it out (for Level based classes). Be aware that my domain name is used in all the package names in the download bundle. The first package declaration in all the files will probably auto-update to your package name when you paste them into your project. However, when the import code refers to the packages that we have created ...GOSpec (in the previous chapter) and …Level (later in this chapter) you will probably need to change the domain name and possibly the project name manually in some or maybe all of the files that import ...GOSpec and …Level.

If you want to type everything then you will just need to add a new class of the correct name by right-clicking the appropriate folder and selecting New | Java Class.

Let's talk about another pattern.

The Singleton pattern

The Singleton pattern is as the name suggests is a pattern that is used when we want only one of something. And more importantly, that we need to absolutely guarantee we only have one of something. The something I refer to is an instance of a class. Furthermore, the Singleton pattern is also used when we want to allow global access to some of its data or methods. The class can then be used from anywhere within a project and yet is also guaranteeing that all parts/classes of the project that access the class are using the exact same instance.

Part of the Singleton conundrum is simple. To make parts of it available to any other class you simply make the methods public and static.

Tip

See Chapter 8: Object-Oriented Programming for a reminder about static variables.

But how do we guarantee that only one instance can ever be created? We will look at the code next but as a look-ahead what we will do is create a class which has a private constructor. Remember that a private method can only be called from within the class itself. And a public and static method that creates an instance then returns a reference- provided an instance has not already been created- and if it has then a reference to the existing instance is returned. This implies that the class will hold a reference to its own instance. Let's look at this with some sample code.

The Singleton code

Here is the class declaration and it contains just one variable. A private and static instance of an object that is the same type as the class itself.

class SingletonClass {

private static SingletonClass mOurInstance;
}

The name of the class is not relevant just that the name of the class is the same as the type being declared.

Next, we can look at the constructor method.

private SingletonClass() {
   // This is only here to prevent instantiation
}

It has the same name as the class as do all constructor methods but note it is private. When a method is private it can only be called by code within the class. Note that depending upon the needs of the project, it is perfectly acceptable to have some code in the constructor, just as long as the constructor is private.

This next method is default access and returns an object of type SingletonClass. Take a look over the code.

// Calling this method is the only way to get a SingletonClass
static SingletonClass getInstance(Context context) {
   
   if(mOurInstance == null) {
          mOurInstance = new SingletonClass();
   }

   return mOurInstance;
}

As the class is default access, any code in the same package can call the method. In addition, because it is static, it can be called without an instance of the class. Now look at the code in the body. The first line checks whether the private member, mOurInstance has been initialized with if(mOurInstance == null). If the object has not been initialized (is null) then the private constructor is called, and the instance is initialized. The final line of code returns a reference to the private instance. Also note as will be the case in the platform game, it might not even be necessary to return an instance.

Now we add a method that actually does something. After all, a class must have a purpose.

static void someUsefulMethod() {
   // Do something useful
}

Note the previous method, someUsefulMethod is static so it too, like getInstance can be called without a reference to the class. This is why I said the getInstance method doesn't necessarily have to return an instance of the class.

Next, we add another method. Note that it is not static.

void someOtherUsefulMethod() {
   // Do something else useful
}

As someOtherUsefulMethod is not static, an instance of the class would be needed in order to call it. So, in this specific case getInstance would need to return a reference to the object.

Now let's see how we could use our new class in some other class of our project. First, we declare an instance of SingletonClass but as we cannot call the constructor we initialize it by calling the static getInstance method.

SingletonClass sc = SingletonClass.getInstance();

The getInstance method will check whether the member SingletonClass object needs to be initialized and if required calls the constructor. Either way, getInstance returns a reference to the private member instance of SingletonClass which initializes sc.

Now we can use the two methods that actually do something useful.

// Call the static method
SingletonClass.someUsefulMethod();

// Call the other method
sc.someOtherUsefulMethod();

The first method, someUsefulMethod is called without using a reference because it is static. The second method is called using the sc reference we initialized using getInstance.

Note

It might surprise you to learn that the Singleton pattern is controversial. It's very use is discouraged even banned in some situations. There are a number of reasons for this but in one-person or small-team projects many of the objections are either not relevant or much less relevant. Android Studio even has a way to auto-generate a singleton. If you are interested in a discussion about the use of the Singleton pattern then a quick Google will bring up strong condemnations, spirited defences and even heated arguments about its use. I suggest you read this article because it gives a fairly balanced view on Singleton and from a game development perspective. http://gameprogrammingpatterns.com/singleton.html. Note that the article discusses Singleton in the context of a different programming language, C++ but the discussion is still useful.

Tip

If you are going for an interview for a programming job very soon you need to read the previous information box. Otherwise enjoy your Singletons.

Next, we will learn about the Java HashMap class and then we will get to code a Singleton for real.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.68.131