1. Game Development
  2. Programming
Gamedevelopment

Quick Tip: The OOP Principle of Abstraction

by
Difficulty:BeginnerLength:ShortLanguages:
This post is part of a series called Beginner's Guide to OOP.
Quick Tip: The OOP Principle of Encapsulation
Quick Tip: The OOP Principle of Inheritance

We’re almost done with this series on object-oriented programming, and in this article we’ll discuss the OOP principle of abstraction - that is, generalising an object - and its use in game development.

Note: Although this tutorial is written using Java, you should be able to use the same techniques and concepts in almost any game development environment.


What is Abstraction?

Abstraction is the principle of generalization. This requires that we move from a specific instance to a more generalized concept by thinking about the most basic information and function of an object.

This may sound a bit strange, but we are already familiar with the concept of abstraction. For example, if I say the word "car", what do you think of? Odds are we weren't thinking about the same car. I was thinking about a black Mustang Boss 302, which is a specific instance of a car. Neither of us were wrong because the word car is a very general concept of a vehicle that we use for transportation (or recreation in my case).

The same goes for video games. Video games are categorized into groups such as RTS, RPG, Racing, etc.. These groups are all generalized concepts that describe the gameplay of a game. StarCraft II, Elder Scrolls V: Skyrim, and Need for Speed are all specific instances of these generalized concepts.

Thus, abstraction takes many specific instances of objects and extracts their common information and functions to create a single generalized concept that can be used to describe all the specific instances as one.


Why is it Helpful?

Abstraction is helpful because it strips everything down to its most basic principles. This can help when encapsulating functionality of an object because it can help identify the important information that should be made visible and the unimportant information which can be made hidden.

Abstraction also helps with the Don't Repeat Yourself principle. By taking what a group of objects have in common and abstracting it, we can help prevent redundant code in each object which in turn creates more maintainable code.


How to Apply This Principle

As before, let's use our three games to see some concrete examples of this principle in action.

Asteroids

To start applying abstraction to Asteroids, think about its objects. Recall that the objects for Asteroids were a ship, an asteroid, a flying saucer, and a bullet. Now think about what each of these objects have in common. Do they share any states, behaviors, or functionality? By taking these common elements that all the objects share we are able to abstract those elements into a more generalized class.

For example, a ship, an asteroid, a flying saucer, and a bullet would all share the same behavior for moving across the screen. You could abstract this behavior into an abstract class that holds the common qualities needed to move an object. These qualities would be states such as position and velocity, and the behavior of moving.

The abstracted class in Java could look like the following:

There are other common states, behaviors, and functionality that all the objects share. Can you think of them? These can all be added into one abstract class.

One thing you want to watch out for is the creating a blob class. A blob class is any class which tries to handle everything from a group of objects, even when every object doesn't share the same states, behaviors, and functionality. Just because a ship and a flying saucer can shoot does not mean you should put that behavior into the same abstract class that is used to describe all four objects.

Check out Iain Lobb's tutorial on entity composition for a look at how he avoids this situation.

Tetris

As stated many times before, Tetris has only one object, a Tetrimino. However, this does not prevent Tetris from abstracting some of its functionality. A Tetrimino is drawn in almost the same manner as the playing field and the other game visuals. This means that you could abstract this drawing behavior into a single class that all things drawn to the screen belong to.

(Personally, I like to call such a class Drawable, but Sprite is also a commonly used name.)

Pac-Man

Pac-Man is a bit more interesting in terms of abstraction. Pac-Man, a ghost, and a pac-dot don’t really share any common states, behaviors, or functionality. They can be drawn to the screen similarly, so an abstract class for handling drawing can be created, but not much more than that. So what do you do? In this case, it is perfectly fine to create multiple abstract classes to organize the code.

Start with the class to handle drawing for all three objects. Next, take away the pac-dot from the group since it is the object that really doesn't belong with the others. That leaves Pac-Man and a ghost. Now think about what these two objects have in common and create another abstract class for these objects. This class could hold states such as direction and speed, and the behavior of moving.

With two abstract classes, you reduce the redundant code that would have been needed to create the three objects, and move it into one location that can be easily changed and modified.


Conclusion

The principle of abstraction helps to reduce redundant code and create more maintainable code. However, abstraction by itself does us nothing if we don’t actually do anything with the abstracted classes. For this, we need to learn about inheritance which will be discussed in the next and final article of this series.

Follow us on Twitter, Facebook, or Google+ to keep up to date with the latest posts.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.