Archive

Posts Tagged ‘Design Patterns’

The Factory Pattern

November 6, 2008 Leave a comment

The Factory Pattern applied:

(From xkcd)

Advertisements
Categories: Miscellaneous Tags:

Game Items composed of Visitors

I recently made a response on gamedev.net forums regarding how Items should be designed. I came up with an idea of using the Visitor Pattern to allow for any game entity to be altered by any sort of Item without creating coupling between the entity and Item. Here is my response:

I started typing up a response and realized that perhaps the Visitor Pattern could be of some interesting use in this situation. By using this method, you would be able to create all sorts of visitors; visitors that alter any entity’s HP, visitors that change the state of any entity, visitors that even create a helper character or make the player fly.

The idea of the visitor pattern is that anything (any class) that would like to have the ability to be visited by a visitor simply includes a single method:

void acceptVisitor(Visitor v){ v.visit(this); }

The class should also provide an interface (not Java interface, but setter/getter methods) that the visitor would use to do whatever the visitor wants with the object. This removes coupling between the character and the item (if the item were a visitor), and allows for any new visitors to be added without having to touch the character class (or any class with the acceptVisitor() method).

Now, like I’ve said, I just thought of this idea, so I’ll lay down some example code and I’ll probably be able to determine from that whether or not it is a viable option. So, if you don’t understand the code I’m about to write, check out the Visitor Pattern and come back, but you should be able to see the idea; it’s very simple.

// Perhaps every character (player, enemy, NPC) in your game has a health
// and an (x, y) position
public class Character {
private int health;
private int x_pos;
private int y_pos;

// Constructor
public Character(...){...}

// Visitor method
public void acceptVisitor(Visitor v){
v.visit(this);
}

// Interface (getter/setter methods)
public int getHealth(){ return health; }
public int getXPos()  { return x_pos;  }
public int getYPos()  { return y_pos;  }

public void setHealth(int hp){ health = hp; }
}

Now, you have a Character class (while simple, gets the idea across) that can accept any Visitor. You can create all sorts of visitors (although there wouldn’t be much they could do since the Character only has a health and (x, y) position) and you can apply them (visit) with any Character without having to touch the Character class again.

Now we need to make a Visitor. One issue with the Visitor pattern is that every implementation of the Visitor interface (Java interface)(or abstract class) must provide definitions for each method, even if they don’t care about those methods. We won’t run into that problem in this example, but if you use the pattern in the future you’ll soon see this.

So, here’s the basic Visitor interface

public interface Visitor {
public void visit(Character c);
}

Remember, our Item‘s will be visitors to Characters, so each Item must implement this Visitor interface and define the method. This is where you can make whatever you want, but to show you the possibilities I’ll make a visitor that alters a Characters health and a visitor that creates a helper NPC.

// This could be a HealthPotion, or perhaps an object HealthPotion could contain
// a HealthVisitor? Something to consider
public class HealthVisitor implements Visitor {
private int amount;

// Constructor
public HealthVisitor(int amount){
this.amount = amount;
}

public void visit(Character c){
c.setHealth( c.getHealth() + amount );
}
}

public class CreateSidekickVisitor implements Visitor {
// Constructor
public CreateSidekickVisitor(){}

public void visit(Character c){
int x = c.getXPos() + 5;
int y = c.getYPos() + 5;

// Some NPC class, for example Sidekick, created right next to the Character
Character sidekick = new Sidekick(x, y);
}
}

I can see that you would probably want to create an Item class to not only provide the necessary variables for the visitors, but to encapsulate and hide the visitation methods. The Item class would have the abstract method use(), similar to your action() method. Then, the concrete implementations of the Item would invoke their own visitors on whatever Character the item is set to be used on. It could look like this:

public interface Item {
public void use(Character c);
}

public HealthPotion implements Item {
private Visitor healthVisitor;
private int     amount;

// Constructor
public HealthPotion(int amount){
// Create the HealthVisitor and provide it with the necessary information
healthVisitor = new HealthVisitor(amount);
this.amount   = amount;
}

// Define use()
public void use(Character c){
c.acceptVisitor(healthVisitor);
}
}

Now to use the Item, simply call the use() method

// Somewhere in your game
Item healthPotion = new HealthPotion(10); // a HealthPotion that restore 10 HP

// Assuming your have an inventory system, and that healthPotion is in your
// Characters inventory, this method call would be made from within your Character class
healthPotion.use(this); // if this method is in your Character class, 'this' would be your Character

After writing all this, it seems to be an interesting idea for Item‘s. Although this limited example may not show the flexibility in a system like this, it’s easy to see what is possible. For example, you could have an Item have multiple visitors, and when you use the item it could boost a characters health (HealthVisitor), give them a sidekick (CreateSidekickVisitor), and enhance their current weapon with fire (EnchantWeaponWithFireVisitor)(using the Decorator pattern on their current weapon)…and all from a single use() invoked on a single Item.

Categories: Game Development Tags:

The Lone Visitor

February 28, 2008 3 comments

The Visitor Pattern has some serious power. It’s just begging to be tossed into a data structure. Unfortunately, I don’t have much of any data structures going on other than some ArrayLists. But, powerful none the less.

I decided to use the Visitor Pattern for drawing my game entities to the screen. So, I created a Visitor interface declaring some visit() methods for all the entities in my game (Ship and Projectile). Then, I made a concrete class called Draw2DVisitor, which, as you may guess, draws things in 2D.

Prior to implementing this Visitor, the Ships and Projectiles had the capability to draw themselves. Although this works and is a common method, you’re stuck with graphics. What if for debugging purposes you wanted to skip graphics and instead print to the screen all the information about where your entities are located? Well if you provided an interface for all kinds of Visitors to use, you could simply create a PrintStringVisitor that printed this information to the screen. Amazing.

So after removing the draw capabilities from all entities and creating the Draw2DVisitor class, I implemented the Visitor into the game. Unfortunately, I quickly ran into a minor but annoying problem. Due to the design of my game loop, the graphics for the window are instantiated every iteration of the game loop, which means I have to provide this new graphics setting to the Draw2DVisitor so it knew where to draw the entities. Well, the only way the Visitor gets this information is through its constructor, which meant I had to declare a variable for the Visitor outside of the game loop, and instantiate a new Draw2DVisitor every iteration of the game loop, providing it the newly created graphics setting. This bothered me. I don’t need to be creating a new Visitor every iteration of the game loop, that’s a lot of unnecessary object creation! But I couldn’t see any way around it due to the already implemented graphics.

Singleton saves the day! Wait a minute. I don’t need any more than one Draw2DVisitor anyways since the single instance is passed around to every entity, why not make it a Singleton and restrict instantiation? Well, it turned out to fit nicely. I changed the Draw2DVisitor class to a Singleton, and provided a static method to retrieve the single instance of the Draw2DVisitor. Since the Draw2DVisitor needs a Graphics2D setting to draw to, I simply added this as a parameter into the static retrieve method. Now when the retrieve method is called, it sets its internal Graphics2D variable to the given parameter, and returns the single instance of the Draw2DVisitor.

Now, each iteration through the game loop, rather than instantiating a new Draw2DVisitor, a simple method is called to retrieve the single Draw2DVisitor and set the appropriate Graphics2D. Job well done Singleton.

Categories: Assignments Tags: ,

Four Patterns Demonstration

February 19, 2008 Leave a comment

I ended up writing so much in the accompanying email of the project file, I thought I’d put that here to describe the design.

The program simulates a teacher at school. A Teacher is created, and then Students are created and given a random favorite design pattern. The Students are then divided into classrooms, and the Teacher goes to each classroom and attempts to drill the design principle of the day into their minds. He then quizzes the Students afterwards on what and how he just taught them the design principle. The Students will not only remember what principle he taught them, but also his tone of voice as well as any manners that the he had.

Two things are randomized that alter the outcome of the program:

– Each Student’s single favorite pattern is chosen at random. This determines whether they will change State when the Teacher announces the pattern of the day.

– Each classroom is assigned random Students. Depending on the number of Students in the classroom whose favorite pattern matches the pattern the Teacher will be teaching (i.e. the number of Students who are paying attention), the State of the Teacher will change.

Let me explain where the 4 patterns are applied:

The Strategy Pattern – A Teacher has a SpeakBehavior (a certain tone) and this SpeakBehavior is determined by the State of the Teacher.

The Observer Pattern – When a Teacher enters a classroom, all the Students observe the Teacher. Then the Teacher announces the pattern of the day, and the Students remove themselves as an Observer from the Teacher if the announced pattern is not their favorite.

The Decorator Pattern – The SpeakBehavior classes may be randomly wrapped by a FunnyManner or WeirdManner.

The State Pattern – The State of the Teacher is determined by how many Students are observing it (paying attention). If the Teacher has already taught 2 classrooms today, and if the Teacher is not in a bad mood (bad state), then the Teacher will be in a Tired state. The State of the Teacher changes the SpeakBehavior of the Teacher, and may even decide (at random) to decorate the SpeakBehavior with a FunnyManner or WeirdManner.

Categories: Assignments Tags: ,

Recipe for Success: Implementing the State Pattern

February 14, 2008 Leave a comment

The State Pattern – Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Implementing the State Pattern:

  1. Fortunately, the State Pattern is a simple concept, and it’s uses are obvious. To implement the pattern in your project, you must first find something that may have various states. This is no complex task; a state is something as simple as Hungry, Tired, Angry, Alive, Dead, Sleeping, Attacking, Defending, Running, Walking, Stationary (Immobile), Waiting, etc. You want to make sure that whatever you choose has more than one state; if it only has one state, then it’s not really a state to begin with, but it’s rather the definition of what that object is.
  2. Now that you’ve found a Finite State Machine (something with multiple states), you need to decide explicitly what those various states will be. For example, you’ve decided a dog will be your FSM (Finite State Machine), then perhaps the states of the dog could be Hungry, Tired, Sleeping (quite a lazy dog).
  3. Now decide what within your FSM (our dog) changes depending on the state that it’s in. For example, if our Dog was in a Hungry state, it might look for food, but if it’s in a Tired state, it might look for a place to sleep. Usually you will be choosing methods that vary depending on the state. In this case, say there was only one method that varied depending on the state of the dog; what the dog’s looking for. The method signature might be: public void lookForSomething();. Now take this method signature and copy it (don’t erase it from the dog class).
  4. Now create a new hierarchy, either with an abstract base class or an interface, that declares (not defines) these methods — lookForSomething() — that you chose in step 3. This hierarchy will now be explicitly for use within your Dogs. If you have other animals that these states may apply to, you could use this hierarchy for them as well, but usually you will have a new hierarchy of states for each FSM that you have.
  5. Now, create subclasses within your State hierarchy that define each of the various states that your FSM will be using. In our example, you would create HungryState, TiredState, and SleepingState subclasses. Now each of these classes must define the abstract methods that were declared in the base class. You would write a definition in each subclass for the lookForSomething() method. In the HungryState, the method might tell the Dog to look for something to eat. In the TiredState, the method might tell the Dog to look for a place to sleep. In the SleepingState, the method might not do anything; you could just leave it blank. This is a viable option because as you know, if you’re sleeping you’re not going to look for something. Therefore, it is okay to leave the method definition blank in the SleepingState, or you might want to send output notifying the caller that the Dog is sleeping.
  6. You need to have an instance variable somewhere of the type of FSM that your states will be applied to. In our example, our abstract base class DogState would have a variable of type Dog. This is necessary for the various states so they have a Dog to change, otherwise they would just be definitions of methods that do something on their own, not change the way something acts. So, if you created your State hierarchy with an interface, you would have to add a variable of type Dog in each of the subclasses, but if you use an abstract class you could put that variable in the base class for every subclass to inherit.
  7. Now, within your FSM, you need to add some new member variables, one (or many) for each of the possible states, plus one for the current state. So in our Dog class, we would add four new variables of type State, and it would look something like this:
    • class Dog {
    • State hungryState;
    • State tiredState;
    • State sleepingState;
    • State currentState;
    • … }
  8. Now in the constructor of the Dog, you would create a new object of the various state subclasses, and assign those to the appropriate variables.
  9. Now, go back to your methods in the Dog class, in our case just the lookForSomething() method. Within this method, you just delegate the task of lookForSomething() to the currentState. The definition of the lookForSomething() in the Dog would look like: currentState.lookForSomething();. This will invoke the correct method definition depending on what state the Dog is in.
  10. When you make your checks on the Dogs hunger level and tired level, you would add an assignment to set the Dogs currentState = hungryState if its hunger level was low enough, or currentState = tiredState if it was tired enough.
  11. Now when lookForSomething() is called on the Dog, the task will be delegated to the currentState of the dog, and an appropriate execution of the method will occur. If currentState = tiredState, when lookForSomething() is called, the definition provided in the TiredState class will be executed.
Categories: Assignments Tags: ,

The Current State of Things

February 14, 2008 Leave a comment

The State Pattern is used far and wide throughout games. Two common uses for it apply to:

  1. The state of the game
  2. – Opening/Introduction
    – Main Menu
    – Loading
    – Running
    – Paused
    – Closing/Exiting

  3. The state of the units/characters
  4. – Damaged
    – Full
    – Upgraded

This is what I plan to implement into my game as well. I currently have a Game class, so I will add in a few States, particularly an OpeningState, a RunningState, and a ClosingState. As for my Ships, I will have the EnemyShips contain a DamagedState and a FullState, while the PlayerShip will contain a DamagedState, FullState, and UpgradedState.

So far I’ve not run into any problems. I’ve implemented the Ship states already and they’re working properly, but I haven’t started on the Game states. Although I’ve got the Ship states added, I don’t have any of the AI created in these states yet.

As for graphics, I’ve got them up and running, but I currently don’t have all the animations (frames) that I want implemented yet, and I haven’t found the BlasterBeam and Torpedo images that I want to use yet, so I have some images just for building purposes. I’ve got the PlayerShip movement and primary weapon fire methods added. They can be seen here:
Photobucket

Photobucket

Photobucket
Notice the jet on the Ship blasts out the back when it accelerates forward/up the screen, and goes away when not accelerating forward/up. I plan to add this same type of animation for the PlayerShip; when it flies to the left the ship leans left, and when it flies to the right the ship leans right.

Categories: Assignments Tags: ,

Recipe for Success: Implementing the Decorator Pattern

February 8, 2008 Leave a comment

Decorator Pattern – Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

How to implement the Decorator Pattern:

  1. Take into consideration a class hierarchy, preferably one with many subclasses. The pattern applies very well when you have several features that a class of yours is comprised of. Rather than creating a subclass for every possible combination of these features, you want to create a Decorator for each individual feature. The Decorator must extend the class that it is going to be decorating, since a Decorator wraps itself around an object that it is decorating, and then stands in place of the decorated object. Therefore, the object and decorator must be of the same type. You can achieve this either through extending a class or implementing an interface.
  2. Now that you have a particular hierarchy that you want to change, you need to separate (but keep within the same hierarchy) your concrete classes from your decorator classes. For example, when you order a House Coffee with A Shot of Espresso and Whip Cream, your concrete class would be the House Coffee, and the Decorators would be A Shot of Espresso and Whip Cream. Remember, your Decorators must extend the same base class as your concrete classes.
  3. Within your new hierarchy, you should have a base class (Beverage), then a few concrete subclasses (HouseCoffee, DecafCoffee, etc…), and another abstract subclass as your decorator (BeverageDecorator). Within your abstract Decorator class, you need to include a member variable of type Beverage (whatever your base class is; whatever you want to decorate). When you decorate an object, that object is stored in this member variable. In the constructor for a Decorator, add a Beverage parameter, because when you construct a Decorator you must give it a Beverage to Decorate. Then, you should have all of your various features extending the Decorator class (BeverageDecorator). The features would be something like EspressoShot, WhipCream, etc.
  4. The idea of the Decorators is that they can modify the behaviors of the object they decorate. Using our example, each Decorator would add a cost to the total amount. After you’ve decorated your HouseCoffee with EspressoShot and WhipCream, when you call the cost() method of the Beverage, the call will pass through each decorator, where that decorator will add its own cost to the returning amount. Therefore, your Decorators must have a common functionality with your concrete classes (this should be implied since they all extend the same base class). If your Decorators do not, they probably shouldn’t be decorating the object.
  5. Now, to use the Decorators, it is simple. Here is an example:
Beverage beverage = new HouseCoffee();
beverage = new EspressoShot(beverage);
beverage = new WhipCream(beverage);
beverage.getCost();
Categories: Assignments Tags: ,