Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
XNA 4.0 Game Development by Example: Beginner's Guide
XNA 4.0 Game Development by Example: Beginner's Guide

XNA 4.0 Game Development by Example: Beginner's Guide: The best way to start creating your own games is simply to dive in and give it a go with this Beginner’s Guide to XNA. Full of examples, tips, and tricks for a solid grounding.

Arrow left icon
Profile Icon Kurt Jaegers
Arrow right icon
Free Trial
Full star icon Full star icon Full star icon Full star icon Half star icon 4.3 (20 Ratings)
Paperback Sep 2010 428 pages 1st Edition
eBook
Can$44.98 Can$49.99
Paperback
Can$61.99
Subscription
Free Trial
Arrow left icon
Profile Icon Kurt Jaegers
Arrow right icon
Free Trial
Full star icon Full star icon Full star icon Full star icon Half star icon 4.3 (20 Ratings)
Paperback Sep 2010 428 pages 1st Edition
eBook
Can$44.98 Can$49.99
Paperback
Can$61.99
Subscription
Free Trial
eBook
Can$44.98 Can$49.99
Paperback
Can$61.99
Subscription
Free Trial

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing
Table of content icon View table of contents Preview book icon Preview Book

XNA 4.0 Game Development by Example: Beginner's Guide

Chapter 2. Flood Control – Underwater Puzzling

It was just another day at the bottom of the ocean until an explosion in one of the storage bays cracked the protective dome around Deep Sea Research Lab Alpha. Now the entire place is flooding, and the emergency pump system is a chaotic jumble of loose parts.

This chapter focuses on the following concepts:

  • Using the Content Pipeline to load textures from disk

  • Creating classes to divide code into logical units

  • Recursively evaluating the status of the game board to check for scoring chains

  • Drawing textures using the SpriteBatch.Draw() method

  • Managing simple game states

Designing a puzzle game


The Puzzler has always been a popular game genre. From old standbys like Tetris to modern crazes like Bejeweled, puzzle games are attractive to players because they do not require a long-term time investment or a steep learning curve.

The game mechanic is the heart of any good puzzle game. This mechanic is usually very simple, with perhaps a few twists to keep the players on their toes.

In Flood Control, the player will be faced with a board containing 80 pieces of pipe. Some will be straight pipes and some will be curved. The objective of the game is to rotate the pipes to form a continuous line to pump water from the left side of the board to the right side of the board.

Completing a section of pipe drains water out of the base and scores points for the player, but destroys the pipes used. New pipes will fall into place for the player to begin another row.

Time for action – set up the Flood Control project


  1. Open Visual Studio Express Edition (If it is already open, select Close Solution from the File menu so you are starting with an empty slate).

  2. In the Visual Studio window, open the File menu and select New Project...

  3. Under Project Type, make sure XNA Game Studio 4.0 is selected.

  4. Under Templates, select Windows Game (4.0).

  5. Name the project Flood Control.

  6. Click on OK.

  7. Right-click on Flood ControlContent (Content) in the Solution Explorer window and select Add | New Folder. Name the folder Textures.

  8. Add another folder under Flood ControlContent (Content) and name the folder Fonts.

  9. Download the 0669_02_GRAPHICPACK.zip file from the book's companion website and extract the files to a temporary folder.

  10. Back in Visual Studio, right-click on Textures in the Content project and click on Add | Existing Item. Browse to the folder where you extracted the 0669_02_GRAPHICPACK files and highlight all of them. Click on Add to add them to your project.

What just happened...

Introducing the Content Pipeline


The Flood ControlContent (Content) project inside Solution Explorer is a special kind of project called a Content Project. Items in your game's content project are converted into .XNB resource files by Content Importers and Content Processors.

If you right-click on one of the image files you just added to the Flood Control project and select Properties, you will see that for both the Importer and Processor, the Content Pipeline will use Texture – XNA Framework. This means that the Importer will take the file in its native format (.PNG in this case) and convert it to a format that the Processor recognizes as an image. The Processor then converts the image into an .XNB file which is a compressed binary format that XNA's content manager can read directly into a Texture2D object.

There are Content Importer/Processor pairs for several different types of content—images, audio, video, fonts, 3D models, and shader language effects files. All of these content types...

Time for action – reading textures into memory


  1. Double-click on Game1.cs in Solution Explorer to open it or bring it to the front if it is already open.

  2. In the Class Declarations area of Game1 (right below SpriteBatch spriteBatch;), add:

    Texture2D playingPieces;
    Texture2D backgroundScreen;
    Texture2D titleScreen;
  3. Add code to load each of the Texture2D objects at the end of LoadContent():

    playingPieces = Content.Load<Texture2D>(@"Textures\Tile_Sheet");
    backgroundScreen = Content.Load<Texture2D>(@"Textures\Background");
    titleScreen = Content.Load<Texture2D>(@"Textures\TitleScreen");
    

What just happened?

In order to load the textures from disk, you need an in-memory object to hold them. These are declared as instances of the Texture2D class.

A default XNA project sets up the Content instance of the ContentManager class for you automatically. The Content object's Load() method is used to read .XNB files from disk and into the Texture2D instances declared earlier.

One thing to note...

Sprites and sprite sheets


As far as XNA and the SpriteBatch class are concerned, a sprite is a 2D bitmapped image that can be drawn either with or without transparency information to the screen.

Tip

Sprites vs. Textures

XNA defines a "sprite" as a 2D bitmap that is drawn directly to the screen. While these bitmaps are stored in Texture2D objects, the term "texture" is used when a 2D image is mapped onto a 3D object, providing a visual representation of the surface of the object. In practice, all XNA graphics are actually performed in 3D, with 2D sprites being rendered via special configurations of the XNA rendering engine.

The simple form of the SpriteBatch.Draw() call that you used in Chapter 1 when drawing squares only needed three parameters: a Texture2D to draw, a Rectangle indicating where to draw it, and a Color to specify the tint to overlay onto the sprite.

Other overloads of the Draw() method, however, also allow you to specify a Rectangle representing the source area within the Texture2D...

Classes used in Flood Control


While it would certainly be possible to simply pile all of the game code into the Game1 class, the result would be difficult to read and manage later on. Instead, we need to consider how to logically divide the game into classes that can manage themselves and help to organize our code.

A good rule of thumb is that a class should represent a single thing or type of thing. If you can say "This object is made up of these other objects" or "This object contains these objects", consider creating classes to represent those relationships.

The Flood Control game contains a game board made up of 80 pipes. We can abstract these pipes as a class called GamePiece, and provide it with the code it needs to handle rotation and provide the code that will display the piece with a Rectangle that can be used to pull the sprite off the sprite sheet.

The game board itself can be represented by a GameBoard class, which will handle managing individual GamePiece objects and be responsible...

The GamePiece class


The GamePiece class represents an individual pipe on the game board. One GamePiece has no knowledge of any other game pieces (that is the responsibility of the GameBoard class), but it will need to be able to provide information about the pipe to objects that use the GamePiece class. Our class has the following requirements:

  • Identify the sides of each piece that contain pipe connectors

  • Differentiate between game pieces that are filled with water and that are empty

  • Allow game pieces to be updated

  • Automatically handle rotation by changing the piece type to the appropriate new piece type

  • Given one side of a piece, provide the other sides of the piece in order to facilitate determining where water can flow through the game board

  • Provide a Rectangle that will be used when the piece is drawn, to locate the graphic for the piece on the sprite sheet

Identifying a GamePiece

While the sprite sheet contains thirteen different images, only twelve of them are actual game pieces (the last...

Time for action – build a GamePiece class – declarations


  1. Switch back to your Visual C# window if you have your image editor open.

  2. Right-click on Flood Control in Solution Explorer and select Add | Class…

  3. Name the class GamePiece.cs and click on Add.

  4. At the top of the GamePiece.cs file, add the following to the using directives already in the class:

    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework;
  5. In the class declarations section, add the following:

      public static string[] PieceTypes = 
      { 
        "Left,Right", 
        "Top,Bottom", 
        "Left,Top", 
        "Top,Right",
        "Right,Bottom", 
        "Bottom,Left",
        "Empty"
      };
    
      public const int PieceHeight = 40;
      public const int PieceWidth = 40;
    
      public const int MaxPlayablePieceIndex = 5;
      public const int EmptyPieceIndex = 6;
    
      private const int textureOffsetX = 1;
      private const int textureOffsetY = 1;
      private const int texturePaddingX = 1;
      private const int texturePaddingY = 1;
    
      private string pieceType = "";
    ...

Time for action – building a GamePiece class: constructors


  1. Add two constructors to your GamePiece.cs file after the declarations:

      public GamePiece(string type, string suffix)
      {
          pieceType = type;
          pieceSuffix = suffix;
      }
    
      public GamePiece(string type)
      {
          pieceType = type;
          pieceSuffix = "";
      }

What just happened?

A constructor is run when an instance of the GamePiece class is created. By specifying two constructors, we will allow future code to create a GamePiece by specifying a piece type with or without a suffix. If no suffix is specified, an empty suffix is assumed.

Updating a GamePiece

When a GamePiece is updated, you can change the piece type, the suffix, or both.

Time for action – GamePiece class methods – part 1 – updating


  1. Add the following methods to the GamePiece class:

      public void SetPiece(string type, string suffix)
      {
          pieceType = type;
          pieceSuffix = suffix;
      }
      
      public void SetPiece(string type)
      {
          SetPiece(type,"");
      }
    
      public void AddSuffix(string suffix)
      {
          if (!pieceSuffix.Contains(suffix))
              pieceSuffix += suffix;
      }
    
      public void RemoveSuffix(string suffix)
      {
          pieceSuffix = pieceSuffix.Replace(suffix, "");
      }

The first two methods are overloads with the same name, but different parameter lists. In a manner similar to the GamePiece constructors, code that wishes to update a GamePiece can pass it a piece type, and optionally a suffix.

Additional methods have been added to modify suffixes without changing the pieceType associated with the piece. The AddSuffix() method first checks to see if the piece already contains the suffix. If it does, nothing happens. If it does not, the suffix value...

Time for action – GamePiece class methods – part 2 – rotation


  1. Add the RotatePiece() method to the GamePiece class:

      public void RotatePiece(bool Clockwise)
      {
          switch (pieceType)
          {
              case "Left,Right":
                  pieceType = "Top,Bottom";
                  break;
              case "Top,Bottom":
                  pieceType = "Left,Right";
                  break;
              case "Left,Top":
                  if (Clockwise)
                      pieceType = "Top,Right";
                  else
                      pieceType = "Bottom,Left";
                  break;
              case "Top,Right":
                  if (Clockwise)
                      pieceType = "Right,Bottom";
                  else
                      pieceType = "Left,Top";
                  break;
              case "Right,Bottom":
                  if (Clockwise)
                      pieceType = "Bottom,Left";
                  else
                      pieceType = "Top,Right";
                  break;
              case "Bottom,Left":
                  if (Clockwise)
                ...

Time for action – GamePiece class methods – part 3 – connection methods


  1. Add the GetOtherEnds() method to the GamePiece class:

      public string[] GetOtherEnds(string startingEnd)
      {
          List<string> opposites = new List<string>();
    
          foreach (string end in pieceType.Split(','))
          {
              if (end != startingEnd)
                  opposites.Add(end);
          }
           return opposites.ToArray();
      }
  2. Add the HasConnector() method to the GamePiece class:

      public bool HasConnector(string direction)
      {
          return pieceType.Contains(direction);
      }

The GetOtherEnds() method creates an empty List object for holding the ends we want to return to the calling code. It then uses the Split() method of the string class to get each end listed in the pieceType. For example, the Top,Bottom piece will return an array with two elements. The first element will contain Top and the second will contain Bottom. The comma delimiter will not be returned with either string.

If the end in question...

Time for action – GamePiece class methods – part 4 – GetSourceRect


  1. Add the GetSourceRect() method to the GamePiece class:

      public Rectangle GetSourceRect()
      {
          int x = textureOffsetX;
          int y = textureOffsetY;
            
          if (pieceSuffix.Contains("W"))
              x += PieceWidth + texturePaddingX;
    
          y += (Array.IndexOf(PieceTypes, pieceType) * 
               (PieceHeight + texturePaddingY));
    
    
          return new Rectangle(x, y, PieceWidth, PieceHeight);
      }

What just happened?

Initially, the x and y variables are set to the textureOffsets that are listed in the GamePiece class declaration. This means they will both start with a value of one.

Because the sprite sheet is organized with a single type of pipe on each row, the x coordinate of the Rectangle is the easiest to determine. If the pieceSuffix variable does not contain a W (signifying that the piece is filled with water), the x coordinate will simply remain 1.

If the pieceSuffix does contain the letter W (indicating the pipe...

The GameBoard class


Now that we have a way to represent pieces in memory, the next logical step is to create a way to represent an entire board of playing pieces.

The game board is a two-dimensional array of GamePiece objects, and we can build in some additional functionality to allow our code to interact with pieces on the game board by their X and Y coordinates.

The GameBoard class needs to:

  • Store a GamePiece object for each square on the game board

  • Provide methods for code using the GameBoard to update individual pieces by passing calls through to the underlying GamePiece instances

  • Randomly assign a piece type to a GamePiece

  • Set and clear the "Filled with water" flags on individual GamePieces

  • Determine which pipes should be filled with water based on their position and orientation and mark them as filled

  • Return lists of potentially scoring water chains to code using the GameBoard

Time for action – create the GameBoard.cs class


  1. As you did to create the GamePiece class, right-click on Flood Control in Solution Explorer and select Add | Class... Name the new class file GameBoard.cs.

  2. Add the using directive for the XNA framework at the top of the file:

    using Microsoft.Xna.Framework;
  3. Add the following declarations to the GameBoard class:

      Random rand = new Random();
    
      public const int GameBoardWidth = 8;
      public const int GameBoardHeight = 10;
    
      private GamePiece[,] boardSquares = 
        new GamePiece[GameBoardWidth, GameBoardHeight];
      private List<Vector2> WaterTracker = new List<Vector2>();

What just happened?

We used the Random class in SquareChase to generate random numbers. Since we will need to randomly generate pieces to add to the game board, we need an instance of Random in the GameBoard class.

The two constants and the boardSquares array provide the storage mechanism for the GamePiece objects that make up the 8 by 10 piece board.

Finally, a List of...

Time for action – initialize the game board


  1. Add a constructor to the GameBoard class:

      public GameBoard()
      {
          ClearBoard();
      }
  2. Add the ClearBoard() helper method to the GameBoard class:

      public void ClearBoard()
      {
          for (int x = 0; x < GameBoardWidth; x++)
              for (int y = 0; y < GameBoardHeight; y++)
                  boardSquares[x, y] = new GamePiece("Empty");
      }

What just happened?

When a new instance of the GameBoard class is created, the constructor calls the ClearBoard() helper method, which simply creates 80 empty game pieces and assigns them to each element in the array.

Tip

Helper methods

Why not simply put the two for loops that clear the board into the GameBoard constructor? Splitting the work into methods that accomplish a single purpose greatly helps to keep your code both readable and maintainable. Additionally, by splitting ClearBoard() out as its own method we can call it separately from the constructor. When we add increasing difficulty levels in Chapter...

Time for action – manipulating the game board


  1. Add public methods to the GameBoard class to interact with GamePiece:

      public void RotatePiece(int x, int y, bool clockwise)
      {
          boardSquares[x, y].RotatePiece(clockwise);
      }
    
      public Rectangle GetSourceRect(int x, int y)
      {
          return boardSquares[x, y].GetSourceRect();
      }
    
      public string GetSquare(int x, int y)
      {
          return boardSquares[x, y].PieceType;
      }
    
      public void SetSquare(int x, int y, string pieceName)
      {
          boardSquares[x, y].SetPiece(pieceName);
      }
    
      public bool HasConnector(int x, int y, string direction)
      {
          return boardSquares[x, y].HasConnector(direction); 
      }
    
      public void RandomPiece(int x, int y)
      {
        boardSquares[x, y].SetPiece(GamePiece.PieceTypes[rand.Next(0, 
             GamePiece.MaxPlayablePieceIndex+1)]);
      }
    

What just happened?

RotatePiece(), GetSourceRect(), GetSquare(), SetSquare(), and HasConnector() methods simply locate the appropriate GamePiece within the boardSquares array and...

Time for action – filling in the gaps


  1. Add the FillFromAbove() method to the GameBoard class.

    public void FillFromAbove(int x, int y)
    {
        int rowLookup = y - 1;
    
        while (rowLookup >= 0)
        {
            if (GetSquare(x, rowLookup) != "Empty")
            {
                SetSquare(x, y,
                  GetSquare(x, rowLookup));
                SetSquare(x, rowLookup, "Empty");
                rowLookup = -1;
            }
            rowLookup--;
        }
    }

What just happened?

Given a square to fill, FillFromAbove() looks at the piece directly above to see if it is marked as Empty. If it is, the method will subtract one from rowLookup and start over until it reaches the top of the board. If no non-empty pieces are found when the top of the board is reached, the method does nothing and exits.

When a non-empty piece is found, it is copied to the destination square, and the copied piece is changed to an empty piece. The rowLookup variable is set to -1 to ensure that the loop does not continue to run.

Generating new pieces...

Time for action – generating new pieces


  1. Add the GenerateNewPieces() method to the GameBoard class:

    public void GenerateNewPieces(bool dropSquares)
    {
    
        if (dropSquares)
        {
            for (int x = 0; x < GameBoard.GameBoardWidth; x++)
            {
                for (int y = GameBoard.GameBoardHeight - 1; y >= 0; y--)
                {
                    if (GetSquare(x, y) == "Empty")
                    {
                        FillFromAbove(x, y);
                    }
                }
            }
        }
    
        for (int y = 0; y < GameBoard.GameBoardHeight; y++)
            for (int x = 0; x < GameBoard.GameBoardWidth; x++)
            {
                if (GetSquare(x, y) == "Empty")
                {
                    RandomPiece(x, y);
                }
            }
    }

What just happened?

When GenerateNewPieces() is called with "true" passed as dropSquares, the looping logic processes one column at a time from the bottom up. When it finds an empty square it calls FillFromAbove() to pull a filled square from above into that location...

Time for action – water in the pipes


  1. Add a method to the GameBoard class to clear the water marker from all pieces:

      public void ResetWater()
      {
          for (int y = 0; y < GameBoardHeight; y++)
              for (int x = 0; x < GameBoardWidth; x++)
                  boardSquares[x,y].RemoveSuffix("W");
      }
  2. Add a method to the GameBoard class to fill an individual piece with water:

      public void FillPiece(int X, int Y)
      {
          boardSquares[X,Y].AddSuffix("W");
      }

What just happened?

The ResetWater() method simply loops through each item in the boardSquares array and removes the W suffix from the GamePiece. Similarly, to fill a piece with water, the FillPiece() method adds the W suffix to the GamePiece. Recall that by having a W suffix, the GetSourceRect() method of GamePiece shifts the source rectangle one tile to the right on the sprite sheet, returning the image for a pipe filled with water instead of an empty pipe.

Propagating water

Now that we can fill individual pipes with water, we can...

Time for action – making the connection


  1. Add the PropagateWater() method to the GameBoard class:

      public void PropagateWater(int x, int y, string fromDirection)
      {
          if ((y >= 0) && (y < GameBoardHeight) &&
              (x >= 0) && (x < GameBoardWidth))
          {
              if (boardSquares[x,y].HasConnector(fromDirection) &&
                  !boardSquares[x,y].Suffix.Contains("W"))
              {
                  FillPiece(x, y);
                  WaterTracker.Add(new Vector2(x, y));
                  foreach (string end in
                           boardSquares[x,y].GetOtherEnds(fromDirection))
                      switch (end)
                            {
                          case "Left": PropagateWater(x - 1, y, "Right");
                              break;
                          case "Right": PropagateWater(x + 1, y, "Left");
                              break;
                          case "Top": PropagateWater(x, y - 1, "Bottom");
                              break;
             ...

Building the game


We now have the component classes we need to build the Flood Control game, so it is time to bring the pieces together in the Game1 class.

Declarations

We only need a handful of game-wide declarations to manage things like the game board, the player's score, and the game state.

Time for action – Game1 declarations


  1. Double click on the Game1.cs file in Solution Explorer to reactivate the Game1.cs code file window.

  2. Add the following declarations to the Game1 class member declaration area:

    GameBoard gameBoard;
    
    Vector2 gameBoardDisplayOrigin = new Vector2(70, 89);
    
    int playerScore = 0;
    
    enum GameStates { TitleScreen, Playing };
    GameStates gameState = GameStates.TitleScreen;
    
    Rectangle EmptyPiece = new Rectangle(1, 247, 40, 40);
    
    const float MinTimeSinceLastInput = 0.25f;
    float timeSinceLastInput = 0.0f;

What just happened?

The gameBoard instance of GameBoard will hold all of the playing pieces, while the gameBoardDisplayOrigin vector points to where on the screen the board will be drawn. Using a vector like this makes it easy to move the board in the event that you wish to change the layout of your game screen.

As we did in SquareChase, we store the player's score and will display it in the window title bar.

In order to implement a simple game state mechanism, we define...

Time for action – updating the Initialize() method


  1. Update the Initialize() method to include the following:

    this.IsMouseVisible = true;
    graphics.PreferredBackBufferWidth = 800;
    graphics.PreferredBackBufferHeight = 600;
    graphics.ApplyChanges();
    gameBoard = new GameBoard();

What just happened?

After making the mouse cursor visible, we set the size of the BackBuffer to 800 by 600 pixels. On Windows, this will size the game window to 800 by 600 pixels as well.

The constructor for the GameBoard class calls the ClearBoard() member, so each of the pieces on the gameBoard instance will be set to Empty.

The Draw() method – the title screen

In the declarations section, we established two possible game states. The first (and default) state is GameStates.TitleScreen, indicating that the game should not be processing actual game play, but should instead be displaying the game's logo and waiting for the user to begin the game.

Time for action – drawing the screen – the title screen


  1. Modify the Draw() method of Game1 to include the code necessary to draw the game's title screen after GraphicsDevice.Clear(Color.CornflowerBlue);

    if (gameState == GameStates.TitleScreen)
    {
        spriteBatch.Begin();
        spriteBatch.Draw(titleScreen,
            new Rectangle(0, 0,
                this.Window.ClientBounds.Width,
                this.Window.ClientBounds.Height),
            Color.White);
        spriteBatch.End();
    }
  2. Run the game and verify that the title screen is displayed. You will not be able to start the game however, as we haven't written the Update() method yet.

  3. Stop the game by pressing Alt + F4.

What just happened?

The title screen is drawn with a single call to the Draw() method of the spriteBatch object. Since the title screen will cover the entire display, a rectangle is created that is equal to the width and height of the game window.

The Draw() method – the play screen

Finally, we are ready to display the playing pieces on the screen...

Time for action – drawing the screen – the play screen


  1. Update the Draw() method of the Game1 class to add the code to draw the game board after the code that draws the title screen:

    if (gameState == GameStates.Playing)
    {
        spriteBatch.Begin();
    
        spriteBatch.Draw(backgroundScreen,
            new Rectangle(0, 0,
                this.Window.ClientBounds.Width,
                this.Window.ClientBounds.Height),
            Color.White);
    
        for (int x = 0; x < GameBoard.GameBoardWidth; x++)
            for (int y = 0; y < GameBoard.GameBoardHeight; y++)
            {
                int pixelX = (int)gameBoardDisplayOrigin.X + 
                    (x * GamePiece.PieceWidth);
                int pixelY = (int)gameBoardDisplayOrigin.Y + 
                    (y * GamePiece.PieceHeight);
    
                spriteBatch.Draw(
                    playingPieces,
                    new Rectangle(
                      pixelX, 
                      pixelY, 
                      GamePiece.PieceWidth, 
                      GamePiece.PieceHeight),
             ...

Time for action – scores and scoring chains


  1. Add a method to the Game1 class to calculate a score based on the number of pipes used:

    private int DetermineScore(int SquareCount)
    {
        return (int)((Math.Pow((SquareCount/5), 2) + SquareCount)*10);
    }
  2. Add a method to evaluate a chain to determine if it scores and process it:

    private void CheckScoringChain(List<Vector2> WaterChain)
    {
    
        if (WaterChain.Count > 0)
        {
            Vector2 LastPipe = WaterChain[WaterChain.Count - 1];
    
    
            if (LastPipe.X == GameBoard.GameBoardWidth - 1)
            {
                if (gameBoard.HasConnector(
                    (int)LastPipe.X, (int)LastPipe.Y, "Right"))
                {
                    playerScore += DetermineScore(WaterChain.Count);
    
                    foreach (Vector2 ScoringSquare in WaterChain)
                    {
                        gameBoard.SetSquare((int)ScoringSquare.X,
                            (int)ScoringSquare.Y, "Empty");
                    }
                }
            }
        }
    }

What just happened?

DetermineScore...

Time for action – handling mouse input


  1. Add the HandleMouseInput() helper method to the Game1 class:

    private void HandleMouseInput(MouseState mouseState)
    {
    
        int x = ((mouseState.X -
            (int)gameBoardDisplayOrigin.X) / GamePiece.PieceWidth);
    
        int y = ((mouseState.Y -
            (int)gameBoardDisplayOrigin.Y) / GamePiece.PieceHeight);
    
        if ((x >= 0) && (x < GameBoard.GameBoardWidth) &&
          (y >= 0) && (y < GameBoard.GameBoardHeight))
        {
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                gameBoard.RotatePiece(x, y, false);
                timeSinceLastInput = 0.0f;
            }
    
            if (mouseState.RightButton == ButtonState.Pressed)
            {
                gameBoard.RotatePiece(x, y, true);
                timeSinceLastInput = 0.0f;
            }
        }
    }

What just happened?

The MouseState class reports the X and Y position of the mouse relative to the upper left corner of the window. What we really need to know is what square...

Time for action – letting the player play


  1. Modify the Update() method of Game1.cs by adding the following before the call to base.Update(gameTime):

    switch (gameState)
    {
        case GameStates.TitleScreen:
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                gameBoard.ClearBoard();
                gameBoard.GenerateNewPieces(false);
                playerScore = 0;
                gameState = GameStates.Playing;
            }
            break;
    
        case GameStates.Playing:
            timeSinceLastInput +=
              (float)gameTime.ElapsedGameTime.TotalSeconds;
    
            if (timeSinceLastInput >= MinTimeSinceLastInput)
            {
                HandleMouseInput(Mouse.GetState());
            }
    
            gameBoard.ResetWater();
    
            for (int y = 0; y < GameBoard.GameBoardHeight; y++)
            {
                CheckScoringChain(gameBoard.GetWaterChain(y));        
            }
    
            gameBoard.GenerateNewPieces(true);
    
            break;
    }

What just happened?

The Update() method performs two different functions...

Play the game


You now have all of the components assembled, and can run Flood Control and play!

Summary


You now have a working Flood Control game. In this chapter we have looked at:

  • Adding content objects to your project and loading them into textures at runtime using an instance of the ContentManager class

  • Dividing the code into classes that represent objects in the game

  • Building a recursive method

  • Use the SpriteBatch.Draw() method to display images

  • Divide the Update() and Draw() code into different units based on the current game state

In Chapter 3, we will spruce up the Flood Control game, adding animation by modifying the parameters of the SpriteBatch.Draw() method and creating text effects in order to make the game visually more appealing.

Left arrow icon Right arrow icon

Key benefits

  • Dive headfirst into game creation with XNA
  • Four different styles of games comprising a puzzler, a space shooter, a multi-axis shoot 'em up, and a jump-and-run platformer
  • Games that gradually increase in complexity to cover a wide variety of game development techniques
  • Focuses entirely on developing games with the free version of XNA
  • Packed with many suggestions for expanding your finished game that will make you think critically, technically, and creatively
  • Fresh writing filled with many fun examples that introduce you to game programming concepts and implementation with XNA 4.0
  • A practical beginner's guide with a fast-paced but friendly and engaging approach towards game development

Description

XNA Game Studio enables hobbyists and independent game developers to easily create video games. It gives you the power to bring your creations to life on Windows, the Xbox 360, the Zune, and the Windows Phone platforms. But before you give life to your creativity with XNA, you need to gain a solid understanding of some game development concepts.This book covers both the concepts and the implementations necessary to get you started on bringing your own creations to life with XNA. It details the creation of four games, all in different styles, from start to finish using the Microsoft XNA Framework, including a puzzler, space shooter, multi-axis shoot-'em-up, and a jump-and-run platform game. Each game introduces new concepts and techniques to build a solid foundation for your own ideas and creativity. Beginning with the basics of drawing images to the screen, the book then incrementally introduces sprite animation, particles, sound effects, tile-based maps, and path finding. It then explores combining XNA with Windows Forms to build an interactive map editor, and builds a platform-style game using the editor-generated maps. Finally, the book covers the considerations necessary for deploying your games to the Xbox 360 platform.By the end of the book, you will have a solid foundation of game development concepts and techniques as well as working sample games to extend and innovate upon. You will have the knowledge necessary to create games that you can complete without an army of fellow game developers at your back.

Who is this book for?

If you are an aspiring game developer who wants to take a shot at creating games for the Microsoft Windows platform with the XNA Framework, then this book is for you. Using this book, you can get started with creating games without any game development experience. A basic knowledge of C# would be helpful to kick-start your game development, but it's not essential.

What you will learn

  • Install the Microsoft XNA Framework and its required tools
  • Build XNA Game projects and associated XNA Content projects
  • Create a puzzle-style game exploring the concepts of game states, recursion, and 2D animation
  • Add sound effects to your game with a "fire-and-forget" sound effects manager
  • Create a particle system to generate random explosions
  • Implement sound effects, collisions, and particle-based explosions by building a space shooter inside a chaotic asteroid field.
  • Implement the A path-finding algorithm to allow enemies to track down the player
  • Generate tile-based maps and path-finding enemy tanks amidst a storm of bullets in a multi-axis shooter
  • Combine XNA and Windows Forms to create a map editor for a multi-layered tile map engine
  • Run, jump, and squash enemies in a side-scrolling platform using the maps from your editor
  • Modify your creations for the Xbox 360 platform and deploy your games to the console

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Sep 24, 2010
Length: 428 pages
Edition : 1st
Language : English
ISBN-13 : 9781849690669
Vendor :
Microsoft
Concepts :

What do you get with a Packt Subscription?

Free for first 7 days. $19.99 p/m after that. Cancel any time!
Product feature icon Unlimited ad-free access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon 50+ new titles added per month, including many first-to-market concepts and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon Thousands of reference materials covering every tech concept you need to stay up to date.
Subscribe now
View plans & pricing

Product Details

Publication date : Sep 24, 2010
Length: 428 pages
Edition : 1st
Language : English
ISBN-13 : 9781849690669
Vendor :
Microsoft
Concepts :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just Can$6 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just Can$6 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total Can$ 201.97
XNA 4 3D Game Development by Example: Beginner's Guide
Can$69.99
Microsoft XNA 4.0 Game Development Cookbook
Can$69.99
XNA 4.0 Game Development by Example: Beginner's Guide
Can$61.99
Total Can$ 201.97 Stars icon

Table of Contents

9 Chapters
Introducing XNA Game Studio Chevron down icon Chevron up icon
Flood Control – Underwater Puzzling Chevron down icon Chevron up icon
Flood Control – Smoothing Out the Rough Edges Chevron down icon Chevron up icon
Asteroid Belt Assault – Lost in Space Chevron down icon Chevron up icon
Asteroid Belt Assault – Lost in Space
Creating the project
Time for action – creating the Asteroid Belt Assault project
Another definition for "sprite"
Time for action – declarations for the Sprite class
Time for action – Sprite constructor
Time for action – basic Sprite properties
Time for action – animation and drawing properties
Time for action – supporting collision detection
Time for action – adding animation frames
Time for action – updating the Sprite
Time for action – drawing the Sprite
A sprite-based star field
Time for action – creating the StarField class
Time for action – updating and drawing the StarField
Time for action – viewing the StarField in action
Animated sprites – asteroids
Time for action – building the AsteroidManager class
Time for action – positioning the asteroids
Time for action – checking the asteroid's position
Time for action – updating and drawing asteroids
Time for action – bouncing asteroids – part 1
Time for action – bouncing asteroids – part 2
Player and enemy shots
Time for action – adding the ShotManager class
Time for action – firing shots
Time for action – updating and drawing shots
Adding the player
Time for action – creating the PlayerManager class
Time for action – handling user input
Time for action – updating and drawing the player's ship
Enemy ships
Time for action – creating the Enemy class
Time for action – waypoint management
Time for action – enemy update and draw
Time for action – creating the EnemyManager class
Time for action – setting up the EnemyManager class
Time for action – spawning enemies
Time for action – updating and drawing the EnemyManager
Summary
Asteroid Belt Assault – Special Effects Chevron down icon Chevron up icon
Robot Rampage – Multi-Axis Mayhem Chevron down icon Chevron up icon
Robot Rampage – Lots and Lots of Bullets Chevron down icon Chevron up icon
Gemstone Hunter – Put on Your Platform Shoes Chevron down icon Chevron up icon
Gemstone Hunter – Standing on Your Own Two Pixels Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.3
(20 Ratings)
5 star 60%
4 star 25%
3 star 5%
2 star 5%
1 star 5%
Filter icon Filter
Top Reviews

Filter reviews by




Roderick C. Dixon Jan 15, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Great tool for learning XNA. Highly recommend it
Amazon Verified review Amazon
Mark Jan 21, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
As president of the Rockford .NET User Group I get asked to review books, not all of which I actually get around to review for one reason or another. Usually the book is not engaging me and I don't wind up getting deep enough into the book to write a decent review.This book, however is different. It has fully engaged me and I am thoroughly enjoying it. After working through 8 of the 9 chapters I feel I can offer a solid review.Overall the code has been excellent with only a couple minor typos that I've noted and the games have worked as they are supposed to. I'm learning a lot about XNA and vector math. (I've even written my first game!) I love the way the author explains the mathematics of what the code is doing - instead of just saying "this is what the code does", the author takes the time to explain (sometimes with illustrations) exactly how the code does what it does and why it works the way it does.I really like the way the author introduces a topic, then dives into the code, then follows the code with a "What Just Happened?" section that explains what the code just entered is supposed to do. The explanations are clear and easy to understand, but not "dumbed down."This book is proving itself very valuable in my development efforts.Thank you for a great book!
Amazon Verified review Amazon
Pule Nong Jun 27, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I bought an ebook version of this book from the publisher's site. This is a practical hands on approach type of book, just at the end of the first chapter I had already built a game called SquareChase.I am not proficient in C# but I was able to follow along very well. The code is easy to read, understand and follow.You do not need to know C# to read this textbook.The book comprises of 4 games that you build as you go along and all these games are interesting. I have already mentioned SquareChase, the other 3 games are flood control, asteroid belt assault and robot rampage. These games are all engaging and fun to play too.This is a great book. I learned a lot from it despite the fact that I am not familiar with the C# programming language. Although I must mention that I have some programming experience working with PHP. I give this book a 100% rating - 5/5.
Amazon Verified review Amazon
Lance W. Larsen Dec 16, 2010
Full star icon Full star icon Full star icon Full star icon Full star icon 5
[…]Firstly, I'm the president of the Madison .NET User Group […] so I get lots of books to review - I generally don't end up doing so - as I get a chapter or two into them - then start skipping around and don't feel that I've read it thoroughly enough to give it a bad, let alone a good review.So when I DO give something a good review -- it really deserves it.And "XNA 4.0 Game Development by Example: Beginner's Guide" by Kurt Jaegers deserves a GREAT review. I'm not done with it yet, but I'm thoroughly engaged by their writing style - I love the way they they dive head first into code, and then follow it up with a "What Just Happened?" section that does a great job explaining in very simple (but not dumbed down) terms. Go here -- […] -- and look at the "Sample Chapter".On top of their writing style, the content is awesome - totally filling in a lot of the blanks and inspiring me to write new code ( which I'll be using for Windows Phone 7 XNA development ) - so look out for better games and (...wait for it... #shock# %gasp%) potential revenue from games that I publish because this book accelerated my learning new XNA techniques.So, in closing - GREAT book - very WELL written - ENGAGING content - HIGHLY encourage those even at all interested in writing Games to grab this book! And if you enjoy it half as much as I am, you will certainly keep this one close at hand while you're writing XNA code.Check out Kurt Jaegers' site - […]-- nice code here as well...!
Amazon Verified review Amazon
Melibojangles May 27, 2011
Full star icon Full star icon Full star icon Full star icon Full star icon 5
If you have been teaching yourself C#/XNA and are familiar with the concepts needed to create games but are struggling with how to put all those pieces together, this book is for you. For me, this book is just one a-ha moment after another. The code is clean and well documented and focuses on functionality rather than theory. This book is exactly what I needed to move to the next level, and expect to see my game on the Xbox Indie Marketplace soon.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is included in a Packt subscription? Chevron down icon Chevron up icon

A subscription provides you with full access to view all Packt and licnesed content online, this includes exclusive access to Early Access titles. Depending on the tier chosen you can also earn credits and discounts to use for owning content

How can I cancel my subscription? Chevron down icon Chevron up icon

To cancel your subscription with us simply go to the account page - found in the top right of the page or at https://subscription.packtpub.com/my-account/subscription - From here you will see the ‘cancel subscription’ button in the grey box with your subscription information in.

What are credits? Chevron down icon Chevron up icon

Credits can be earned from reading 40 section of any title within the payment cycle - a month starting from the day of subscription payment. You also earn a Credit every month if you subscribe to our annual or 18 month plans. Credits can be used to buy books DRM free, the same way that you would pay for a book. Your credits can be found in the subscription homepage - subscription.packtpub.com - clicking on ‘the my’ library dropdown and selecting ‘credits’.

What happens if an Early Access Course is cancelled? Chevron down icon Chevron up icon

Projects are rarely cancelled, but sometimes it's unavoidable. If an Early Access course is cancelled or excessively delayed, you can exchange your purchase for another course. For further details, please contact us here.

Where can I send feedback about an Early Access title? Chevron down icon Chevron up icon

If you have any feedback about the product you're reading, or Early Access in general, then please fill out a contact form here and we'll make sure the feedback gets to the right team. 

Can I download the code files for Early Access titles? Chevron down icon Chevron up icon

We try to ensure that all books in Early Access have code available to use, download, and fork on GitHub. This helps us be more agile in the development of the book, and helps keep the often changing code base of new versions and new technologies as up to date as possible. Unfortunately, however, there will be rare cases when it is not possible for us to have downloadable code samples available until publication.

When we publish the book, the code files will also be available to download from the Packt website.

How accurate is the publication date? Chevron down icon Chevron up icon

The publication date is as accurate as we can be at any point in the project. Unfortunately, delays can happen. Often those delays are out of our control, such as changes to the technology code base or delays in the tech release. We do our best to give you an accurate estimate of the publication date at any given time, and as more chapters are delivered, the more accurate the delivery date will become.

How will I know when new chapters are ready? Chevron down icon Chevron up icon

We'll let you know every time there has been an update to a course that you've bought in Early Access. You'll get an email to let you know there has been a new chapter, or a change to a previous chapter. The new chapters are automatically added to your account, so you can also check back there any time you're ready and download or read them online.

I am a Packt subscriber, do I get Early Access? Chevron down icon Chevron up icon

Yes, all Early Access content is fully available through your subscription. You will need to have a paid for or active trial subscription in order to access all titles.

How is Early Access delivered? Chevron down icon Chevron up icon

Early Access is currently only available as a PDF or through our online reader. As we make changes or add new chapters, the files in your Packt account will be updated so you can download them again or view them online immediately.

How do I buy Early Access content? Chevron down icon Chevron up icon

Early Access is a way of us getting our content to you quicker, but the method of buying the Early Access course is still the same. Just find the course you want to buy, go through the check-out steps, and you’ll get a confirmation email from us with information and a link to the relevant Early Access courses.

What is Early Access? Chevron down icon Chevron up icon

Keeping up to date with the latest technology is difficult; new versions, new frameworks, new techniques. This feature gives you a head-start to our content, as it's being created. With Early Access you'll receive each chapter as it's written, and get regular updates throughout the product's development, as well as the final course as soon as it's ready.We created Early Access as a means of giving you the information you need, as soon as it's available. As we go through the process of developing a course, 99% of it can be ready but we can't publish until that last 1% falls in to place. Early Access helps to unlock the potential of our content early, to help you start your learning when you need it most. You not only get access to every chapter as it's delivered, edited, and updated, but you'll also get the finalized, DRM-free product to download in any format you want when it's published. As a member of Packt, you'll also be eligible for our exclusive offers, including a free course every day, and discounts on new and popular titles.