350 likes | 431 Views
Object Oriented Analysis & Design. Game Patterns 2. Contents. Observer Factory Method Composite Model-View-Controller Spatial Index Builder Flyweight. Observer. Description
E N D
Object Oriented Analysis & Design Game Patterns 2
Contents • Observer • Factory Method • Composite • Model-View-Controller • Spatial Index • Builder • Flyweight
Observer • Description • Several objects have an interest in the value of one other object. The object being observed maintains a list of observers and notifies the members of the list every time its value changes. • Several enemies are following the player and need to be notified when the player moves so they can adjust their paths. The number of enemies can change at any time and we must be able to add enemies onto the list being observed and remove them from the list at any time.
Observer • Solution • The observed object will • Maintain a list of observers • Allow observers to be added and removed at any time • Notify the observers on the list every time its value changes • The observers will • Implement a method to be notified when the observed object changes • The program will • Add observers to the list for the observed object and remove them as necessary
Factory Method • Description • Provides a method to create instances of a class but delegate the decision as to the particular subclass to create to another class. • Motivation • A character in a game must create a weapon for itself • Knights will be able to create swords and lances • Citizens can create cudgels and slingshots • Wizards can create magic wands • We need to isolate the type of weapon which can be created into the class that created it so that the class using the characters does not need to know the type of weapon to create for each character.
Factory Method • Solution • The solution is to have • A createWeapon() method on the Character class • Make Knight, Citizen and Wizard subclasses of Character • Have the Knight, Citizen and Wizard each override createWeapon() to form the class-specific behaviour
Composite • Description • A game object is composed of several parts and we want all of the parts to move as if they are a single object. • Motivation • The main character in a game can carry various weapons, including a sword, shield, mace and spear. • When the character is carrying these weapons, they must all move with the character. • The character can pick up new weapons or drop weapons at any time. • The character can even piggy back another character who carries his own weapons, or even another character...
Composite • Solution • The solution requires that we recognize • There are objects which can carry other objects and object which cannot carry other objects • The objects which can carry other objects can carry objects just like themselves • We can store the objects being carried as • A vector of objects • But the type of the vector must include all of the objects, so they must all be derived from a common type
Composite class GameObject { virtual void addComponentObject(GameObject o) {} virtual void removeComponentObject(GameObject o) {} } class CompositeGameObject: public GameObject { std::list<GameObject*> parts; void addComponentObject(GameObject o) { parts.push_back(&o); } void removeComponentObject(GameObject o) { parts.remove(o); } }
Model View Controller (MVC) • Description • A game is split into a model holding the data, a view rendering the game on the screen and a controller which performs the logic of the game. • Motivation • Games were originally written as logic which made calls to retrieve data and draw the screen from within the logic code. • Porting to a different graphics system required that both the graphics and logic be rewritten • Changing the data format required that the data and logic be rewritten • We needed to be able to change the data, graphics or logic without affecting the other parts
Model View Controller (MVC) • Solution • The solution is to separate the three parts of the game so that • The code is separate and a change in one does not require a change in the others • There are established interfaces to communicate between the parts • You should be able to • Modify a part without changing its interface • Replace one part with a replacement part and not require any change to the code in the other parts
Spatial Index • Description • An index is built that provides rapid access to the objects in a game based on the location of the objects. • Motivation • The player clicks on the screen with the mouse and we have to rapidly find out if a a game object was clicked on and, if so, which one. • If this takes too long, the frame rate of the game will be slowed • A way to find objects rapidly by their position is needed
Spatial Index • Solution • The solution is to • Split the space of the game into a series of smaller spaces • Recursively split each of the smaller spaces into even smaller spaces • Continue to split the space into smaller subspaces until the required resolution is achieved • Each of the smallest spaces must maintain a list of game objects which exist entirely or partially within the space • The spaces are arranged into a tree structure so that they can be searched rapidly by throwing away a large amount of space every time a new level in the tree is reached.
Spatial Index Quadtree A square is recursively split into smaller squares.
Spatial Index The spatial index must be updated every time an object moves. This is more easily done if the subareas are numbered consistently. 1 2 4 3 1 2 3 4 At every level in the tree, the children are numbered in the same order
Spatial Index 1 2 3 4 1 2 1 2 4 3 4 3 1 2 3 4 1 2 3 4 To go right from red 2 to blue 1, go to grandparent, 3rd child and 1st child To go right from red 3 to blue 4, go to grandparent, 3rd child and 4th child Every move can be pre-computed to find the adjacent area.
Spatial Index • The spatial index is designed to • Rapidly find the objects in a particular position • It will not rapidly • Find the square containing a given object • If you want to rapidly find the square containing a given object you should • Build a secondary index • Use a hashtable with the pointer to every object as the key • The value will be a pointer to the square containing the object
Flyweight • Description • Allows a game to maintain a large number of small objects with different properties without consuming large amounts of memory. • Motivation • Games sometimes deal with large numbers of objects such as • Bullets • Particles • Insects • If each of these objects are different from the rest and have a large number of properties we will consume large amounts of memory
Flyweight • Consider • The hero is under attack by a swarm of spiders • Each spider might have • A colour • A bitmap • A speed • A size • Height it can jump • AI behaviour • Storing these for hundreds of spiders wastes a lot of space
Flyweight • Solution • There are only a few actual combinations of attributes which actually exist • These can be • represented as attribute groups • Stored in an attribute group repository • References by all object which have the same set of attributes • This will result in • The same set of common attributes shared among many objects • Each object having only 1 pointer to an attribute group
Builder • Description • Separates the representation of an object from the construction of an object. • Motivation • 3D models are stored in one form inside most games but are stored in many different external formats (fbx, obj, collada) • Creating a different model for every external format is a waste since all of the representation of the model remains the same
Builder • Solution • Provide a class for the model representation • Provide a series of classes which can build the internal representation from several external formats • This allows the same model to be built from many formats • It allows for the easy addition of new formats without having to alter the internal representation of the model
Prototype • Description • Reduce the cost of constructing complex objects by creating an instance that is already configured in a common way and allow it to be copied at low cost. • Motivation • You allow each player to create his or her own avatar for the game • The avatar can be selected from the groups soldier, priest and wizard • A new avatar is created and set up with common attributes for that type of avatar each time • This requires code to be maintained and is slow to execute
Prototype • Solution • The solution is to create prototype objects which have common attributes already set • Provide a clone method which will • Create a new instance • Copy all of the attributes to the new instance • Return the new instance • This will • Allow objects with a common set up to be produced quickly • Allow the user to customize them after construction • Reduce the overall construction time