XNA Game-Themed Assignment (XGA)

XGA-100: Implementation Guide

Kelvin Sung
Computing and Software Systems
University of Washington, Bothell
Michael Panitz
Software Programming
Cascadia Community College

1. Topics Covered:

This document explains some of the implementation details found in the example solution to the XGA-100 assignment module.  Please follow this link to find out more about XGA-100 assignment module and all other XGA assignments. Topics covered in this implementation guide include:


It is assumed that you have read the following documents:

  1. The XNA Installation Guide: guides you download and install the XNA SDK and Game Studio Express IDE.

  2. The XNACS1Lib Guide: describes how to work with the XNACS1Lib class.

  3. If you have never worked with XGA assignments before, here is the summary of all XGA implementation guides.

Please download the XNA_Tutorial zip file and unzip this file. It is best to open the project in the Game Studio Express IDE and follow the source code while reading the rest of this implementation guide.


2. Implementation:

Now, compile and run the XNA_Tutorial application. You should see:

Notice that (note: this is the controller keyboard mapping):

Left Trigger: When depressed, the chameleon turns and face left and the circle will move left.

Right Trigger: When depressed, the chameleon turns to face right and the circle will move right.

In addition, notice that the color at the center of the circle reflects the region it is located in. This color will change as the circle center is moved across the boundary between the blue/pink regions. In this application, the two color regions are defined by two constant color rectangles.


The rest of this document explains how these functionality are implemented.


3. Images in the Content/Resources/Textures Folder:

The Resources/Textures folder (in the IDE this can be found under the  Content folder) contains two files, l_chameleon.png and r_chameleon.png. The two files represent the left (l__) facing and right (r_) facing version of the chameleon.

The above figure shows that depending on which of the left or right trigger is depressed the corresponding chameleon image will be mapped onto a square. The textured square will then overlap on top of a circle to create the effect of a "chameleon in a circle". The implementation for texture selection is explained in UpdateWorld.

4. The Source Code Structure:

The source code folder structure and file names are similar to that described in the XNACS1Lib guide. The only difference is that, in this case, the program source code is located in the SwitchAndMod_Guide.cs file (instead of the Game1.cs file). We are going to examine the content of this file in detailed.

Recall that when working with the XNACS1Base class, we need to pay attention to the following 6 specific items:

  1. Declaring and using libraries.
  2. Resources folders (Fonts, Textures, and Audio) and files.
  3. Subclass from XNACS1Base.
  4. Override the two functions:
    1. InitializeWorld()
    2. UpdateWorld()
  5. Understand and know how to use the classes defined in the XNACS1Base class.
  6. Know how to call the input functions to work with the XBOX controller.

Since the provided source code is a working program, the above items has all been properly taken cared for. The functionality we are interested in are implemented in items 2, 3 and 4. We will examine these functions.

Main Class Declaration and Construction

In the beginning of SwitchAndMode_Guide.cs file we can see:

public class SwitchAndMode_Guide : XNACS1Base {

  private const float WORLD_MIN_X = 0.0f; // lower left corner (0, 0)

  private const float WORLD_MIN_Y = 0.0f;

  private const float WORLD_WIDTH = 20.0f; // width is 20.0

XNACS1Circle m_ChameleonBase; // Circle around the Chameleon
XNACS1Rectangle m_Chameleon;  // The Chameleon

  float m_RecWidth;? // width of the two constant color rectangles

  float m_RecHeight;?// Height of the two constant color rectangles


Notice that in this case, we have defined an intuitive coordinate system where the lower-left corner is the origin (0,0), and we have defined the width of the drawing area to be 20 units.


4a. The InitializeWorld() function:

protected override void InitializeWorld() {

   World.SetWorldCoordinate(new Vector2(WORLD_MIN_X, WORLD_MIN_Y), WORLD_WIDTH);

   m_RecHeight = WorldMax.Y - WorldMin.Y; // rectangle covers the height
   m_RecWidth = WORLD_WIDTH/2.0f;         // width is half of area
   // A: The two constant color rectangles in the back
rCenter = new Vector2(m_RecWidth/2.0f, m_RecHeight/2.0f);

   XNACS1Rectangle r = new XNACS1Rectangle(rCenter, m_RecWidth, m_RecHeight);

   r.OutsideColor = Color.LightBlue; // Left rectangle is in light blue

   r.CenterColor = Color.LightBlue;

   rCenter.X += m_RecWidth;   

   r = new XNACS1Rectangle(rCenter, m_RecWidth, m_RecHeight);

   r.OutsideColor = Color.Pink; // Right rectangle is in pink

   r.CenterColor = Color.Pink;


   // B: Top-most object should be created last

   Vector2 chameleonPos = new Vector2(5.0f, 6.0f);

   m_ChameleonBase = new XNACS1Circle(chameleonPos, 2.0f);

   m_ChameleonBase.OutsideColor = Color.White;

   m_ChameleonBase.CenterColor = Color.White;

   m_Chameleon = new XNACS1Rectangle(chameleonPos, 3.0f, 3.0f, "l_chameleon");

                   // Look left "l_chameleon"


As shown above, we always initialize the coordinate system first. After which:

In both cases, the created primitives (circle and rectangles) will be added to the AutoRedraw set and will be drawn in the application window.

4b. The UpdateWorld() function:

Recall that the UpdateWorld() function is responsible for keeping the application’s state up-to-date. In this case, we need to check the Triggers to move the Chameleon:

protected override void UpdateWorld() {

  // Allows the default game to exit on Xbox 360 and Windows

   if (XNACS1Base.GamePad.ButtonBackClicked())



   // Label A: Pool the left/right triggers

   float deltaL = XNACS1Base.GamePad.Triggers.Left;

   float deltaR = XNACS1Base.GamePad.Triggers.Right;


   // Label B: Update Chameleon texture and audio

   if (deltaR > 0.0f) {

        m_Chameleon.Texture = "r_chameleon"; // right-facing texture

        XNACS1Base.PlayACue("zoom");  // audio response

   } else if (deltaL > 0.0f) {

              m_Chameleon.Texture = "l_chameleon"; // left-facing texture

              XNACS1Base.PlayACue("zoom");  // audio response



   // Label C: Update Chameleon position

   m_Chameleon.CenterX += deltaR - deltaL;      // chameleon position

   World.ClampAtWorldBound(m_Chameleon);        // clamp to window bounds

   m_ChameleonBase.Center = m_Chameleon.Center; // base circle position


   // Label D: Update Chameleon base circle color

   if (m_ChameleonBase.CenterX < m_RecWidth)

        m_ChameleonBase.CenterColor = Color.LightBlue;


        m_ChameleonBase.CenterColor = Color.Pink;


   // Label E: Echo status

   EchoToTopStatus(@"ChameleonBase Position:" + ...);

   EchoToBottomStatus(@"World Min:" ...);


As in most cases, the first operation performed is check for exit status (BackButton clicked). after which, the application state is updated accordingly: 

        Label A: We poll the left and right triggers' states and use those values to update the circle center position. These two delta values will be used to update the position of the chameleon.

        Label B: We use the values of deltaL/R as a hint to determine which of the left/right chameleon texture to use and to provide audio feedback for the user. For example, a value of greater than zero signifies the right trigger is depressed and thus we should use the right-facing chameleon image.

        Label C: We use the values of deltaL/R to update the horizontal position of the chameleon (m_Chameleon.CenterX). After the update, we first clamp Chameleon position to within the application boarder by calling ClampAtWorldBound() before assigning the position to the base circle.

        Label D: We check the current circle position to determine the color to use for drawing the center of the circle.

        Label E: text status update.

Note: Since all primitives are in the AutoDraw set, we do not need to worry about drawing these primitives.

5. Important Observations:

The above implementation demonstrates:  User control of object: notice that the position of the circle is controlled by the user. Values from the input devices (user choice) are used to modify the current values of the circle.

6. Exercises:

1.      Instead of WORLD_WIDTH of 20, change it 30. Now modify all necessary values (including rectangle width) such that the look and behavior of this program remains the same. The important lesson from this exercise is that we can implement the same functionality with different coordinate dimensions. Depending on the graphics and interaction of your applications (assignments) you should design the coordinate range/dimension accordingly.

2.      Add a third color region (e.g., LightGreen) with a third rectangle covering the center third of the drawing area. Change the width of the two existing rectangles such that they only cover the left and right one-third of the drawing area. Now, in UpdateWorld(),?include the logic to compute the proper color such that the m_ChameleonBase's center color will properly reflect that of the three region as user moves the circle left/right.

7. Start the Assignment:

Here is the starter project where the students should start their work to complete the assignment.  We have isolated the logic for computing color into the BackgroundStrip.cs file such that students only need to work on this file. In addition, we have clearly identified regions where students should add in their code: it's between the note that says "STUDENTS: YOU NEED TO WRITE YOUR CODE BELOW:", and "STUDENTS: YOU NEED TO WRITE YOUR CODE ABOVE:" with . In this way students do not need to change anything except for the code that they add in order to complete the assignment.

This document and the related materials are developed with support from Microsoft Research Computer Gaming Initiative under the Computer Gaming Curriculum in Computer Science RFP, Award Number 15871.