While the urge to code immediately is strong, its important to spend some time designing the location object. A badly designed object might be unusable, or inefficient, whereas a well designed one is reusable in other applications and elegant in its construction. Since this location will form part of a larger gaming system, we need to make sure our design accommodates the need of the game developer.
Stop to consider what attributes are important for game locations. Obviously we need a description of the room, but what other attributes would be useful? A title for the room would be helpful (not all players like lengthy verbose descriptions, and it would be handy to have a shortened version), and we'll need some sort of structure to store copies of exit objects.
Older styles of programming would suggest an array would be useful for storing exit information. We could use a fixed length array, and store pointers or references to the exits. In the world of object-orientated programming, however, we have the luxury of choice. The most compelling container for exit information is the vector class. If you've never used a vector in Java before, you don't know what you're missing!
A vector object is similar to a linked list, in that we have a sequence of objects which can be easily modified dynamically. We can add a new object, or remove an existing one. This is a very powerful feature! Consider the case of a game which requires an exit appear or disappear at different stages of the game. We can easily accommodate this by using the vector object.
Now that we've discussed the attributes of a location object, and how we intend to store the data, its time to get our hands dirty and write some code. I've written a location object already, which you can download and examine, though for the benefit of clarity and understanding I'll briefly discuss important issues relating to the code.
The location object starts with a class declaration, and then member variables. You'll notice that I've made all the member variables private. This is important! Its bad design to make all your variables public, as other classes can easily modify them without your control. Rather, you should make essential items private, and have get/set methods to access them.
public class Location { // Member variables private String m_roomTitle; private String m_roomDescription; private Vector m_vecExits;
// Returns location title public String getTitle() { return m_roomTitle; } // Assigns location title public void setTitle( String roomTitle ) { m_roomTitle = roomTitle; } // .......... }
The use of the vector object to store exit objects may cause some confusion if you've never used vectors before. Objects can be added to a vector via the addElement(Object) method, and removed from a vector via the removeElement(Object) method. Location provides methods that add/remove exits, rather than exposing the vector object to manipulation by making it public.
// Adds an exit to this location public void addExit ( Exit exit ) { m_vecExits.addElement (exit); } // Removes an exit from this location public void removeExit ( Exit exit ) { if (m_vecExits.contains (exit)) { m_vecExits.removeElement (exit); } }
In some cases, we may want to return an entire vector as in the case of getExits(), which allows the gaming system to see which room the current location must move to. You must always be careful when returning a reference to an object, however! One of the dangers of just returning a reference to a member variable (as with making it public), is that it is possible for an external object to modify it directly.
If we want to return our vector, and maintain its integrity, it is necessary to return a clone of the vector. A clone of a vector contains the same data, but when a clone is changed by an external object, the original is left untouched. If you've used C++ before, you may be familiar with this concept - its passing by value rather than reference.
// Returns a vector of exits public Vector getExits () { // Return a clone, as we don't want an external // object to modify our original vector return (Vector) m_vecExits.clone(); }
The next step is to create the Exit class, which will serve to link locations together.