XNA Game-Themed CS1 Examples (XGC1)

Release 2.0 (XNA V3.1)
2/8/2010

Topic: Topic.4.DecisionStructures
Example: Ex_8.MultipleNestedWithBlocks

Decision Statements: Nested Conditionals, and Obstacles for the Game!


Need (library reference):

References:

Goals:



1. Obtain the example code

Download and unzip the zip file and you will see an ExampleProgram folder. Open the ExampleProgram folder, the EXE folder contains the compiled program and you can double click on the .sln file to work with the source code.

When the game starts, you'll see a screen that looks similar to this:


The game behaves in a manner that is identical to the what was described for the previous tutorial, with several changes:

  1. Internally, we've refactored some code so that instead of initializing all the 'statistics' (number of bounces, number of misses, etc) in InitializeWorld, the code will now call a separate function to do that.

  2. There are several blocks in the middle of the screen. Each block is labeled with a letter and does not move.  If the soccer ball hits one of these blocks, the ball will bounce off the block, and we'll change the message at the top of the screen to remind the player what the last impacted block is..  The blocks are positioned randomly, so that each game will be a little bit different.

Let's examine the source code, change by change


2. Refactoring the Initialization Code:

Let's start with the code refactoring. Code refactoring refers to taking some existing code, and changing it in a way that doesn't change the functionality the code effects, but does change how the code is organized. In this case, we'll take several lines from the InitializeWorld routine, and move those lines into their own function.  On an immediate level, this will improve the readability of the InitializeWorld function, as it will now be clear that those lines initialize the 'statistics' of the game (i.e., the number of times the ball has bounced off a paddle, the number of times the ball was missed, etc).  On a longer-term level, having a function that sets all the statistics to their initial, starting, level will be useful when we allow the user to restart the game.  Eventually, when the player restarts the game, we will call this new function to re-set the statistics to their starting levels.

In order to do this, we will first need to replace the code in InitializeWorld with a call to the new function.  The second thing that we'll do is define the function.



2. Adding Obstacles:  Putting (Labeled) Blocks In The Middle Of The Screen

Now that we've refactored the initialization code, let's add a new feature: we will put a bunch of (labeled) blocks in the middle of the screen.  Since we haven't covered the programming topic of "an array of objects" yet, we will need to keep track of each block individually, which we will do using instance variables.  We will place the blocks a specific distance apart on the X axis, but randomly choose the height (on the Y axis); in order to make it easy to adjust those values, we'll use constants to define those numbers.  Once we've got the instance variables and named constants for the new feature, we'll need to initialize (which involves both creating and placing) all of the blocks.  Finally, we'll create a new function to check for a collision between the ball and any of the blocks, which we will call from UpdateWorld.

Let's examine each of those steps in detail:


FURTHER EXERCISES:

  1. Start from a blank starter project (1000.201, if you need it), and re-do the code from memory as much as possible.  On your first try, do what you can, and keep the above code open so that when you get stuck, you can quickly look up what you forgot (and that after you finish a line, so that you can compare your line to the 'correct' line).  On the next try, do the same thing, but try to use the finished code less.  Repeat this until you can type everything, without refering the tutorial's code.
  2. Refactoring Code
    For this exercise, you should use the same project that was explained in the above tutorial.
    Create a new method, named something like InitializeBlocks, which will create and initialize all the blocks on the screen.  Make sure that instead of doing all this work in InitializeWorld, you call the new InitializeBlocks method, instead. 
  3. Making the blocks into constant objects: Making the blocks readonly
    For this exercise, you should use the same project that was explained in the above tutorial.
    A readonly variable can be initialized when it's declared, or in the constructor, but can't be changed anywhere else.  So after the constructor is done, the variable can't be modified anymore, which makes readonly variables very similar to const variables.  You should be able to make the blocks readonly by:
    1.  putting the word readonly into their declarations (in the same place that you'd put a const), and then
    2. moving everything in the #region "random blocks and their positions" into the Game1 constructor.

Project home page: The Game-Themed Introductory Programming Project.
Kelvin Sung
Computing and Software Systems
University of Washington, Bothell
ksung@u.washington.edu
Michael Panitz
Business And Information Technology
Cascadia Community College
mpanitz@cascadia.eduu

Microsoft Logo This work is supported in part by a grant from Microsoft Research under the Computer Gaming Curriculum in Computer Science RFP, Award Number 15871 and 16531.
2/8/2010