XNA Game-Themed CS1 Examples ( XGC1 ) Release 2.0 (XNA V3.1) 2/8/2010
Topic: Topic.5.RepetitionStructures
Example: Ex_17.ZapGameCompoundLoopTermination

# Zap Game: Compound Logic in Loops

References:

• Pre-requisite: it is assumed that you have read through the prior tutorials, and are familiar with the concepts covered in those tutorials.

Goals:

• In this tutorial, we will:
• Examine compound logic condition for termination, when encountering block.

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:

This version of the 'zap' game looks and plays almost identically to the prior version, which was explained in the 360 tutorial .  The major change is that in this version, we will detect if the enemy's laser beam has hit a block, and if it has, we will stop the beam at that point.  The player's beam will continue to ignore the blocks, as pictured above.

2. Examining The Program:

Let's examine the C# source code that produces the behavior we see on-screen

• Drawing the Enemy's Laser in UpdateWorld():  Version of code in 360 tutorial Version of code in this tutorial ï¿½@ XNACS1Circle lastEnemyCircle = null ; Vector2 EnemyBeam = m_Enemy.Center; while ( EnemyBeam.X > m_Hero.CenterX ) {     EnemyBeam.X -= 1f;     lastEnemyCircle = CreateEnemyPath(EnemyBeam); } ï¿½@ ï¿½@ ï¿½@ ï¿½@ ï¿½@ ï¿½@ ï¿½@ XNACS1Circle lastEnemyCircle = null ; Vector2 EnemyBeam = m_Enemy.Center;   bool blocked = false ; // if enemy zap path has encountered a block   while (!blocked && EnemyBeam.X > m_Hero.CenterX) {     EnemyBeam.X -= 1f;     lastEnemyCircle = CreateEnemyPath(EnemyBeam);       // did this last path-element collide with any of the blocking blocks?     blocked = CollidedWithBlocks(lastEnemyCircle); }
• In order to emphasize the differences between the code provided in the 360 tutorial, and the code provided in this tutorial, we have aligned the loop from the 'enemy zapping' region side-by-side, with the new loop in this tutorial on the right.
• You'll notice that the two loops are very similar.  The major difference is that the code uses a 'compound condition' to determine when to stop.  In a nutshell, the loop should continue as long as the laser beam is not blocked (by one of the Blocks on the screen), and as long as the EnemyBeam's X part hasn't yet been moved to X part of the player's location.
• Because the logic needed to control the loop based on the EnemyBeam.X value is the same as the prior version, we won't discuss that here.  Instead, we'll look at the new material that relates to the compound condition.
• First, we will create a boolean variable (a variable that holds only either true, or false).  Initializing it to false is reasonable because the enemy soccer ball will never overlap with any of the blocks.

bool blocked = false ; // if enemy zap path has encountered a block
• Next,  we'll use the logical AND to check that two things are true in the loop:  (1) the laser beam has not collided with a block ( !blocked  ), and (2), the laser beam has not yet made it to the left side of the screen ( EnemyBeam.X > m_Hero.CenterX ).  Because we need BOTH conditions to be true in order for the loop to continue, we use the logical AND oeprator ( && ) to join them.

while (!blocked && EnemyBeam.X > m_Hero.CenterX)
• After moving the EnemyBeam's X variable over a small amount, and then creating another circle at that location, we check to see if that new location overlaps with any of the blocks, using the CollidedWithBlocks routine.

blocked = CollidedWithBlocks(lastEnemyCircle);
• The CollidedWithBlocks method simply checks if the given circle overlaps with any of the three blocks, by checking each block, one by one.  Note that in them method, we use the logical OR operator, because we want to return true if ANY of the blocks collide with the circle.  Also note that in the method, instead of temporarily storing the true/false result into a local variable, we just return the true/false result directly.

private bool CollidedWithBlocks( XNACS1Circle path)

{

return m_BlockA.Collided(path) || m_BlockB.Collided(path) || m_BlockC.Collided(path);

}

FURTHER EXERCISES::

1. Something