Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
World Cup news
Windows Phone

Microsoft XNA Game Studio 3.0 : Creating Game Components - Objects and Abstraction

12/26/2011 4:08:01 PM
The Great Programmer calls this abstraction. This is the progress that you have made so far:
  • Representing values by named locations (variables)

  • Creating actions that work on variables (statements and blocks)

  • Putting actions into lumps of code to which we can give names. We can reuse these actions and also use them in the design process (methods)

  • Creating things that contain member variables as properties and member methods as actions (objects)

  • Making constructions that contain objects that are related in some way and want to share resources (class hierarchies)

As you think about a design in a more abstract way you will initially describe the actions that are needed in general terms. Rather than looking at specific behavior and low-level detail with statements like "A sprite will draw itself using the spriteRect rectangle and the spriteTexture texture," you are thinking about things in more general terms and saying things like "A sprite will have to draw itself." This is because at the early stages of the design process, you are trying to focus on what things need to do rather than on the specific details of how they do them. Later on, you can come back and fill in precisely how the draw behavior works.

It is frequently the case that different components in your system that share a need for a draw behavior (for example, different kinds of game object) actually implement that draw behavior differently (some might draw a texture, whereas others might just draw a dot or a line), but from the point of view of the top-level design, it is best to think of them as just having the Draw behavior.

1. Creating an Abstract Class in C#

From a C# point of view, you can create abstract classes, which contain placeholders for methods that need to be present when actual instances of the class need to be created. Look at the following code:

public abstract class AbstractSprite
public abstract void Draw (SpriteBatch spriteBatch);

This is a very simple abstract class called AbstractSprite that contains a single Draw method. You would not be able to create an instance of the AbstractSprite class. If you tried as follows, the compiler would reward you with an error:

AbstractSprite s;
s = new AbstractSprite(); // would cause a compilation error

The Draw method is not actually present in the class—it is an abstract placeholder. It is saying to the compiler, "A class that extends AbstractSprite must have a Draw method if you want to make an instance of it."

You could think of an abstract class as a really strict family business. To join the business, you have to be related to someone already in it and be able to do all the things that the business needs. Members of the AbstractSprite business must have a Draw method and be a child of a class in the hierarchy that has AbstractSprite at the base.

2. Extending an Abstract Class

The idea of an abstract class is that it provides a template of behaviors that are required in all the children of the class. We can create a child class called MySprite that satisfies these requirements. In fact, XNA Game Studio makes it very easy to do this. All you have to do is start typing the class declaration, then right-click the parent class name. This action brings up a menu from which you can select the Implement Abstract Class option, as shown in Figure 1.

Figure 1. Implementing an abstract class in XNA Game Studio

When you select the option, an empty child class that contains a placeholder Draw method is created automatically. If the parent class contained many abstract methods, the new class would have a placeholder for each. This is a lovely example of just how an intelligent editor that is aware of the design of the language you are using can make life much easier for the programmer. Figure 2 shows how XNA Game Studio fills in the child class started in Figure 1.

Figure 2. XNA Game Studio filling in an abstract class

The code for MySprite that XNA Game Studio has created allows a program to create an instance of the MySprite class. This is because the MySprite class contains an implementation of the abstract Draw method and therefore fulfills the entry requirements to join the AbstractSprite "club." Here’s the code for this:

public class MySprite : AbstractSprite
public override void Draw(SpriteBatch spriteBatch)
throw new NotImplementedException();

The next thing that you would do is fill in the Draw method with the code that performs the draw behavior for this particular type of sprite. If you forget to do this, you can still create instances of the AbstractSprite class and call the Draw method, but the version of Draw shown here throws an exception and stops the program.

An exception is a way that a program can signal it is unhappy and bring this to the attention of an exception handler that might be able to sort things out . In these situations, things that you are using have thrown exceptions when something bad happens (such as trying to load a texture that isn’t there, or trying to read elements beyond the bounds of an array). This time it is the other way around, in that the code you are writing is signaling that something has gone wrong—in this case, that the programmer has not filled in a placeholder produced by XNA Game Studio.

3. Designing with Abstract Classes

Abstract classes let you design a system by working out what a particular kind of object needs to do and then setting a specification or template to ensure that all the objects of that kind can do these things. If you were using abstraction, you would find those behaviors that are common to all sprites (Draw, Update, BeginGame, and EndGame) and put them in an abstract parent class, so you could be sure that all classes in the sprite hierarchy had those minimum behaviors. The class could even have some data members and non-abstract methods that could be used by all the child classes.

Of course, the fact that a class contains a Draw method does not actually mean that it can draw itself properly. A properly built system also has some tests that can be applied to objects to ensure that they really can do what is needed, just like you should have to pass some kind of interview to join the family business even if your dad owns the company.

4. References to Abstract Parent Classes

You have seen that it is not possible to create an instance of an abstract class like AbstractSprite. This is because if the program ever needed to perform the Draw operation on such an object, it would not know what to do. However, you might find it surprising that you can create references of type AbstractSprite, and in fact, this is a very sensible thing to do. Here’s code that does this:

AbstractSprite anySprite;

anySprite = new MySprite();


This code creates a reference called anySprite of type AbstractSprite. It then sets this to a new MySprite instance and calls Draw on it. You might think that the compiler would take issue with this, but in fact, it is completely happy. A reference to a parent class can always refer to any of the child types. This is because a child is always able to do everything that a parent can. (Note that this is in direct contradiction to real life, in that none of my children seem to have inherited my dancing ability—and they are very relieved about this.)

The compiler knows that an instance of MySprite has a Draw method that can be called when required. This would be true for any child of the AbstractSprite class, although which actual code runs depends on precisely what class is on the end of the reference.

This turns out to be very useful. You might change the design of your game so that all the sprites on the display are managed using an array. You would want to hold a large number of sprites in such an array and not have to worry about precisely what kind of sprites they are. This can be achieved by making the array of type AbstractSprite:

AbstractSprite[] screenSprites = new AbstractSprite[100];

This would create an array that could hold references to 100 sprites, which could be any of the classes that are in the hierarchy that has AbstractSprite as its root. Actually, references like this also work with parent classes that are not abstract, so you could manage the game objects in BreadAndCheese using an array of BaseSprite objects as well.

Top Search -----------------
- Windows Server 2008 R2 : Work with RAID Volumes - Understand RAID Levels & Implement RAID
- Windows Server 2008 R2 Administration : Managing Printers with the Print Management Console
- Configuring Email Settings in Windows Small Business Server 2011
- Windows Server 2008 R2 : Configuring Folder Security, Access, and Replication - Implement Permissions
- Monitoring Exchange Server 2010 : Monitoring Mail Flow
- Windows Server 2008 R2 :Task Scheduler
- Windows Server 2008 R2 : File Server Resource Manager
- Windows Server 2008 R2 : Installing DFS
- Exchange Server 2010 : Managing Anti-Spam and Antivirus Countermeasures
- Windows Server 2008 R2 : Configuring Folder Security, Access, and Replication - Share Folders
Other -----------------
- Creating Transitions and Interactivity (part 2) - Visual State Manager
- Creating Transitions and Interactivity (part 1) - Toolkit Page Transitions
- Silverlight for Windows Phone 7 Toolkit (part 4) - LongListSelector Control
- Silverlight for Windows Phone 7 Toolkit (part 3) - WrapPanel Control
- Silverlight for Windows Phone 7 Toolkit (part 2) - ContextMenu , DatePicker, TimePicker, ListPicker & ToggleSwitch Control
- Silverlight for Windows Phone 7 Toolkit (part 1) - AutoCompleteBox Control
- Windows Phone 7 : Using Media Player to Shuffle Songs in Your Media Library
- Windows Phone 7 : Picking a Photo from Your Media Library
- The Model-View-ViewModel Architecture (part 2) - GalaSoft MVVM Light Toolkit
- The Model-View-ViewModel Architecture (part 1) - MVVM Overview
Most view of day
- Windows Phone 7 : The Silverlight Controls (part 5) - Interactive Controls - CheckBox Controls, RadioButton Controls
- Designing and Configuring Unified Messaging in Exchange Server 2007 : Monitoring and Troubleshooting Unified Messaging (part 2) - Performance Monitors
- System Center Configuration Manager 2007 : Operating System Deployment - Drivers
- Windows Server 2008 : Configuring Server Core after Installation (part 3) - Logging Off, Shutting Down, and Rebooting
- Windows Server 2012 Group Policies and Policy Management : GPO Administrative Tasks - Backing Up and Restoring Domain GPOs
- Integrating BizTalk Server 2010 and Microsoft Dynamics CRM : Communicating from Dynamics CRM to BizTalk Server (part 1) - Setup
- System Center Configuration Manager 2007 : Operating System Install Packages and Image Packages (part 1) - Automated Image Creation and Capture
Top 10
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Avoiding Harmful Attacks, Using the Trust Center
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Adding a Signature Line
- Microsoft Excel 2010 : Protecting and Securing a Workbook - Adding a Digital Signature
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 7) - ISATAP
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 6) - Configuring a DHCPv6 server, IPv6 transition technologies
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 5) - Stateless address autoconfiguration,Stateful address autoconfiguration
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 4) - IPv6 address assignment - Manual address assignment
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 3) - IPv6 address representation
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 2) - Default IPv6 functionality
- Windows Server 2012 : Configuring IPv6/IPv4 interoperability (part 1) - IPv6 concepts and terminology
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
Cars Review