This is an individual lab.
A common travel game is to find the letters in a word on the license plates of vehicles that you see on the road. For example, the license plates ATT-351 and CPO-OO3 would be sufficient to match “CAT”. For this lab, you will be given code that draws cars, buses, and a person moving around a map. As the person comes into contact with a car, that car’s plate will be used to match letters in various keywords. The first keyword you will match is “MSOE”. Your implementation will use the Observer Pattern.
Your instructor will provide a starting point for this lab, possibly by pointing you to this page or through GitHub Classroom. The key class in this is CityMap
. It displays a portion of Milwaukee. This map is just for reference - your game pieces will not actually follow the roads and will even float across the harbor. This map also includes a Museum
represented by a rectangular area you can walk through. The moving objects are subclasses of the abstract class MobileEntity. We use the term “tagging” to mean colliding with another object. The base class Taggable
are those objects that can collide with other objects.
As distributed, the system shows a map with vehicles and a person. There is also a green circle. It serves as a goal for person: if the circle is moved (by moving the mouse), the person walks in that direction. The following diagram shows the relationship between the objects on the map:
The CityMap
has multiple museums and entities. The entities are in an actors
package:
We are giving you code to draw these actors on the map. You will implement a simple game based on a tourist visiting the city and completing challenges. This part, you will write code for one challenge:
In this challenge, the game displays a picture of The Wood Gatherer whenever the person enters the rectangle representing the location of the Milwaukee Art Museum (MAM). This picture is shown in the status area on the right hand side of the screen, as shown in the following image:
When the program starts up, it will display just the message Challenge: Find art
in the status area. Once the user enters the museum, it will display the woodcutter image. The woodcutter image is available in the repository folder src/mketour/img
. You can model the code for loading it after the code that loads the images for the cars, buses, and person. In a later lab you will add code that displays messages when the game player touches (tags) cars and buses. The challenge in those cases will be to tag the vehicles with the appropriate letters in their plates.
Begin by sketching a minimal solution diagram (or another diagram if required by your instructor) that illustrates the Observer pattern for the challenge you are implementing. As you sketch this diagram, think about how the responsibilities of the classes will change.
Plan to make only minimal edits to the existing classes, inserting all new responsibilities into new classes, and only adding minimal code to tie the existing classes to the new ones. Note that it IS OK to extend existing responsibilities of the existing classes. For example,
notifyObservers
in existing methods.instanceof
; you will likely need to use instanceof
when you set up the initial observers, but the observer handlers should not need to do this.How you use the Observer Pattern is one of the many choices you need to make in this assignment. We recommend identifying where the events you care about are generated in the code and making those parts of your code the concrete subjects. The remainder of the pattern classes can be new classes. Thus, only the concrete subjects would need to modify existing code. (As well as instantiating your concrete observers somewhere.) A related question is what data to pass in the operation to update the observers. You could pass the objects being tagged, the subject that is producing the event, or data such as license plates. These choices have no clear answers, and the “best” solution often comes down to the one that makes the most sense to individual students. Do not be afraid to experiment! No matter what you do, make sure how you are using the pattern isolates your observers and your subjects. There should be very little communication between your observers and your subjects.
Your design must satisfy the following constraints:
TagEvent
) as a separate class.Once you are satisfied with your design, begin the implementation. Again, be sure to only make minimal edits to the existing classes to tie them into the new classes you add to support the strategies. Review the above after you have started to make sure you are on the right track.
A major part of this assignment is implementing the Observer Pattern. You are to write your own classes implementing this pattern; do not use Java.util.Observable
or Java.util.Observer
. You may use your own names for the Observer Pattern; it may be helpful to use names that are specific to the problem such as “CarObserver” or “TagObserver.” Solutions should avoid unnecessary casting. For example, you should not need to cast from an Object
to Taggable
. There are, however, sometimes situations where a cast from, for example, MobileEntity
to Car
may be required for some implementations.
One goal of the Observer Pattern (like other patterns) is to simplify future modifications to existing code when supporting new features. You should not need to modify existing classes other than to introduce code tying to new pattern classes. Add only one line of code in CityMap.addEntities()
to support the new challenge. In particular, new GUI code should not be added to the CityMap.
When you submit, check that CityMap.DEBUG_LEVEL
is 0 so any debug code is disabled. These console messages about contacting buses and museums might be useful to you during your development, but large numbers of messages slow down your solution and make it difficult to grade. Make sure all of your output is controlled by DEBUG_LEVEL
.