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 - Visual Basic Edition
XNA 4.0 Game Development by Example: Beginner's Guide - Visual Basic Edition

XNA 4.0 Game Development by Example: Beginner's Guide - Visual Basic Edition: Create your own exciting games with Visual Basic and Microsoft XNA 4.0

eBook
€25.99 €28.99
Paperback
€37.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

XNA 4.0 Game Development by Example: Beginner's Guide - Visual Basic Edition

Chapter 2. Flood Control – Underwater Puzzling

It was just another day on 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.

Designing a puzzle game


The Puzzler has always been a popular game genre. From old standbys such as Tetris, to modern crazes such as 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 interactive pieces of pipe (the rows on the left and right are built into the background image, since they always stay the same). 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...

Time for action – setting up the Flood Control project


  1. Open Visual Studio Express Edition (if it is already open, select Close Solution from the File menu so that 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 2403_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 2403_02_GRAPHICPACK files and highlight all of them. Click on Add to add them to your project.

What...

Introducing the Content Pipeline


The Flood Control Content (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 a .XNB file, which is a compressed binary format that XNA's content manager can read directly into a Texture2D object.

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

Time for action – reading textures into memory


  1. Double-click on Game1.vb 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 Private WithEvents spriteBatch As SpriteBatch), add:

    Private playingPieces As Texture2D
    Private background As Texture2D
    Private titleScreen As Texture2D
  3. Add code to load each of the Texture2D objects at the end of LoadContent():

    playingPieces = Content.Load(Of Texture2D)("Textures\Tile_Sheet")
    background = Content.Load(Of Texture2D)("Textures\Background")
    titleScreen = Content.Load(Of 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...

Sprites and sprite sheets


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

Tip

Sprites versus. 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 through special configurations of the XNA rendering engine.

The simple form of the SpriteBatch.Draw() call that you used in Chapter 1, Introducing XNA Game Studio, when drawing squares only needed two 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...

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 pipe pieces. 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, which are filled with water and which 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 how 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 13 different images, only 12 of them are actual game pieces (the last one is an...

Time for action – build a GamePiece class - declarations


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

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

  3. Name the class GamePiece.vb, and click on Add.

  4. Add the following declarations to the (currently empty) class:

    Public Shared PieceTypes() As String = { 
        "Left,Right", 
        "Top,Bottom", 
        "Left,Top", 
        "Top,Right",
        "Right,Bottom", 
        "Bottom,Left",
        "Empty"
      }
    
      Public Const PieceHeight As Integer = 40
      Public Const PieceWidth As Integer = 40
    
      Public Const MaxPlayablePieceIndex As Integer = 5
      Public Const EmptyPieceIndex As Integer = 6
    
      Private Const textureOffsetX As Integer = 1
      Private Const textureOffsetY As Integer = 1
      Private Const texturePaddingX As Integer = 1
      Private Const texturePaddingY As Integer = 1
    
      Private _pieceType As String = ""
      Private _pieceSuffix As String = ""
  5. Add two properties to retrieve information about the piece...

Time for action – building a GamePiece class – constructors


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

    Public Sub New(type As String, suffix As String)
      _pieceType = type
      _pieceSuffix = suffix
    End Sub
    
    Public Sub New(type As String)
      _pieceType = type
      _pieceSuffix = ""
    End Sub

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 Sub SetPiece(type As String, suffix As String)
      _pieceType = type
      _pieceSuffix = suffix
    End Sub
    
    Public Sub SetPiece(type As String)
      SetPiece(type, "")
    End Sub
    
    Public Sub AddSuffix(suffix As String)
      If Not _pieceSuffix.Contains(suffix) Then
        _pieceSuffix &= suffix
      End If
    End Sub
    
    Public Sub RemoveSufix(suffix As String)
      _pieceSuffix = _pieceSuffix.Replace(suffix, "")
    End Sub

    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 passed...

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


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

    Public Sub RotatePiece(clockwise As Boolean)
      Select Case _pieceType
        Case "Left,Right"
          _pieceType = "Top,Bottom"
        Case "Top,Bottom"
          _pieceType = "Left,Right"
        Case "Left,Top"
          If (clockwise) Then
            _pieceType = "Top,Right"
          Else
            _pieceType = "Bottom,Left"
          End If
        Case "Top,Right"
          If (clockwise) Then
            _pieceType = "Right,Bottom"
          Else
            _pieceType = "Left,Top"
          End If
        Case "Right,Bottom"
          If (clockwise) Then
            _pieceType = "Bottom,Left"
          Else
            _pieceType = "Top,Right"
          End If
        Case "Bottom,Left"
          If clockwise Then
            _pieceType = "Left,Top"
          Else
            _pieceType = "Right,Bottom"
          End If
      End Select
    End Sub

What just happened?

The only information the RotatePiece() method needs is a rotation direction. For straight pieces, rotation direction...

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


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

    Public Function GetOtherEnds(startingEnd As String) As String()
      Dim Opposites As List(Of String) = New List(Of String)()
    
        For Each pipeEnd As String In _pieceType.Split(CChar(","))
          If pipeEnd <> startingEnd Then
            Opposites.Add(pipeEnd)
          End If
        Next
    
      Return Opposites.ToArray()
    End Function
  2. Add the HasConnector() method to the GamePiece class:

    Public Function HasConnector(direction As String) As Boolean
      Return _pieceType.Contains(direction)
    End Function

What just happened?

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...

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


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

    Public Function GetSourceRectangle() As Rectangle
      Dim x As Integer = textureOffsetX
      Dim y As Integer = textureOffsetY
    
      If _pieceSuffix.Contains("W") Then
        x += PieceWidth + texturePaddingX
      End If
    
      y += (Array.IndexOf(PieceTypes, _pieceType) *(PieceHeight + texturePaddingY))
    
      Return New Rectangle(x, y, PieceWidth, PieceHeight)
    End Function

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 1.

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 _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 – creating 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.vb.

  2. Add the following declarations to the GameBoard class:

    Private rand As New Random()
    
    Public Const GameBoardWidth As Integer = 7
    Public Const GameBoardHeight As Integer = 9
    
    Private playingPieces As Texture2D
    Private emptyPiece As Rectangle
    
    Private boardSquares(GameBoardWidth, GameBoardHeight) As GamePiece
    
    Private waterTracker As New List(Of 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 Texture2D (playingPieces) and the Rectangle (emptyPiece) will be passed in when the class is created and hold the sprite sheet used to draw the board and the location of the sheet's empty piece square.

The two constants and the...

Time for action – initializing the game board


  1. Add a constructor to the GameBoard class:

    Public Sub New(pieceTexture As Texture2D, emptyArea As Rectangle)
      playingPieces = pieceTexture
      emptyPiece = emptyArea
      ClearBoard()
    End Sub
  2. Add the ClearBoard() helper method to the GameBoard class:

    Public Sub ClearBoard()
      Dim x, y As Integer
      For x = 0 To GameBoardWidth
        For y = 0 To GameBoardHeight
          boardSquares(x, y) = New GamePiece("Empty")
        Next
      Next
    End Sub

What just happened?

When a new instance of the GameBoard class is created, we store the texture and rectangle values that we will need for drawing, and 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 work up into methods that accomplish a single purpose greatly helps to keep your code both readable and maintainable. Additionally...

Time for action – manipulating the GameBoard


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

    Public Sub RotatePiece(x As Integer, y As Integer,
      clockwise As Boolean)
      boardSquares(x, y).RotatePiece(clockwise)
    End Sub
    
    Public Function GetSourceRect(
      x As Integer, y As Integer) As Rectangle
      Return boardSquares(x, y).GetSourceRectangle()
    End Function
    
    Public Function GetSquare(x As Integer, y As Integer) As String
      Return boardSquares(x, y).PieceType
    End Function
    
    Public Sub SetSquare(x As Integer, y As Integer, pieceType As String)
      boardSquares(x, y).SetPiece(pieceType)
    End Sub
    
    Public Function HasConnector(x As Integer, y As Integer, direction As String) As Boolean
      Return boardSquares(x, y).HasConnector(direction)
    End Function
    
    Public Sub RandomPiece(x As Integer, y As Integer)
      boardSquares(x, y).SetPiece(GamePiece.PieceTypes(
        rand.Next(0, GamePiece.MaxPlayablePieceIndex + 1)))
    End Sub

What just happened?

RotatePiece(), GetSourceRect(), GetSquare(), SetSquare...

Time for action – filling in the gaps


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

    Public Sub FillFromAbove(x As Integer, y As Integer)
      Dim rowLookup As Integer = y - 1
    
      Do While (rowLookup >= 0)
        If GetSquare(x, rowLookup) <> "Empty" Then
          SetSquare(x, y, GetSquare(x, rowLookup))
          SetSquare(x, rowLookup, "Empty")
          rowLookup = -1
        End If
        rowLookup -= 1
      Loop
    End Sub

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

We can create a single...

Time for action – generating new pieces


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

    Public Sub GenerateNewPieces(dropSquare As Boolean)
      Dim x, y As Integer
    
      If dropSquare Then
        For x = 0 To GameBoardWidth
          For y = GameBoardHeight To 0 Step -1
            If GetSquare(x, y) = "Empty" Then
              FillFromAbove(x, y)
            End If
          Next
        Next
      End If
    
      For y = 0 To GameBoardHeight
        For x = 0 To GameBoardWidth
          If GetSquare(x, y) = "Empty" Then
            RandomPiece(x, y)
          End If
        Next
      Next
    
    End Sub

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. By using the step 1 in the for loop for the Y coordinate, we can make the loop run backwards instead of the default forward direction. When it finds an empty square, it calls FillFromAbove() to pull a filled square from above into that location.

The reason the processing order is important here...

Time for action – water in the pipes


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

    Public Sub ResetWater()
      Dim x, y As Integer
      For x = 0 To GameBoardWidth
        For y = 0 To GameBoardHeight
          boardSquares(x, y).RemoveSufix("W")
        Next
      Next
    End Sub
  2. Add a method to the GameBoard class to fill an individual piece with water:

    Public Sub FillPiece(x As Integer, y As Integer)
      boardSquares(x, y).AddSuffix("W")
    End Sub

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 write the...

Time for action – making the connection


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

    Public Sub PropagateWater(x As Integer, y As Integer, fromDirection As String)
    
      If (y >= 0) And (y <= GameBoardHeight) And
        (x >= 0) And (x <= GameBoardWidth) Then
        If boardSquares(x, y).HasConnector(fromDirection) And
          Not (boardSquares(x, y).PieceSuffix.Contains("W")) Then
          FillPiece(x, y)
          waterTracker.Add(New Vector2(x, y))
          For Each pipeEnd As String In 
            boardSquares(x, y).GetOtherEnds(fromDirection)
            Select Case pipeEnd
              Case "Left"
                PropagateWater(x - 1, y, "Right")
              Case "Right"
                PropagateWater(x + 1, y, "Left")
              Case "Top"
                PropagateWater(x, y - 1, "Bottom")
              Case "Bottom"
                PropagateWater(x, y + 1, "Top")
            End Select
          Next
        End If
      End If
    End Sub
  2. Add the GetWaterChain() method to the GameBoard class:

    Public Function GetWaterChain(y As Integer...

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, such as the game board, the player's score, and the game state.

Time for action – Game1 declarations


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

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

    Private _gameBoard As GameBoard
    Private gameBoardDisplayOrigin As New Vector2(70, 89)
    Private playerScore As Integer = 0
    
    Private Enum GameStates
      TitleScreen
      Playing
    End Enum
    
    Private gameState As GameStates = GameStates.TitleScreen
    
    Private EmptyPiece As Rectangle = New Rectangle(1, 247, 40, 40)
    
    Private Const MinTimeSinceLastInput As Single = 0.25
    Private timeSinceLastInput As Single = 0

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 our game screen.

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

Time for action – updating the Initialize() method


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

    Me.IsMouseVisible = True
    Me.graphics.PreferredBackBufferWidth = 800
    Me.graphics.PreferredBackBufferHeight = 600
    graphics.ApplyChanges()
  2. Update the LoadContent() method to include the following after three texture files have been loaded:

    _gameBoard = New GameBoard(playingPieces, EmptyPiece)

What just happened?

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

The constructor for the GameBoard class calls the ClearBoard() method, 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...

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 Then
      spriteBatch.Begin()
      spriteBatch.Draw(titleScreen,New Rectangle(0, 0,Me.Window.ClientBounds.Width,Me.Window.ClientBounds.Height),
        Color.White)
      spriteBatch.End()
    End If
  2. Run the game and verify that the title screen is displayed. You will not be able to start the game yet, however, as we have not 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. We will accomplish this by using a simple...

Time for action – drawing the screen – the play screen


  1. In the GameBoard class, add the Draw() method to allow the game board to draw itself:

    Public Sub Draw(
      spriteBatch As SpriteBatch,
      DisplayOrigin As Vector2)
    
      Dim x As Integer, y As Integer
    
      For x = 0 To GameBoardWidth
        For y = 0 To GameBoardHeight
          Dim pixelX As Integer = CInt(DisplayOrigin.X + (x * GamePiece.PieceWidth))
          Dim pixelY As Integer = CInt(DisplayOrigin.Y + (y * GamePiece.PieceHeight))
    
          spriteBatch.Draw(
            playingPieces,New Rectangle(
              pixelX,pixelY,GamePiece.PieceWidth,GamePiece.PieceHeight),EmptyPiece,Color.White)
    
          spriteBatch.Draw(
            playingPieces,New Rectangle(
              pixelX,pixelY,GamePiece.PieceWidth,GamePiece.PieceHeight),GetSourceRect(x, y),Color.White)
        Next
      Next
    End Sub
  2. Update the Draw() method of the Game1 class to add the code to call the Draw() method of GameBoard. Place this code after the code that draws the title screen:

    If gameState = GameStates.Playing...

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 Function DetermineScore(squareCount As Integer) As Integer
      Return CInt(
        ((Math.Pow((squareCount / 5), 2) + squareCount) * 10))
    End Function
  2. Add a method to evaluate a chain to determine if it scores and process it:

    Private Sub CheckScoringChain(WaterChain As List(Of Vector2))
      If (WaterChain.Count > 0) Then
        Dim LastPipe As Vector2 = WaterChain(WaterChain.Count - 1)
    
        If LastPipe.X = gameBoard.GameBoardWidth Then
          If _gameBoard.HasConnector(
            CInt(LastPipe.X),
            CInt(LastPipe.Y), 
          "Right") Then
            playerScore += DetermineScore(WaterChain.Count)
            For Each thisPipe As Vector2 In WaterChain
              _gameBoard.SetSquare(
                CInt(thisPipe.X),
                CInt(thisPipe.Y),
              "Empty")
            Next
          End If
        End If
      End If
    End Sub

What just happened?

DetermineScore() accepts the number...

Time for action – handling mouse input


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

    Private Sub HandleMouseInput(mouseInfo As MouseState)
      Dim x, y As Integer
    
      x = mouseInfo.X - CInt(gameBoardDisplayOrigin.X)
      y = mouseInfo.Y - CInt(gameBoardDisplayOrigin.Y)
    
      x = x \ GamePiece.PieceWidth
      y = y \ GamePiece.PieceHeight
    
      If (x >= 0) And (x <= GameBoard.GameBoardWidth) And
        (y >= 0) And (y <= GameBoard.GameBoardHeight) Then
        If mouseInfo.LeftButton = ButtonState.Pressed Then
          _gameBoard.RotatePiece(x, y, False)
          timeSinceLastInput = 0
        End If
        If mouseInfo.RightButton = ButtonState.Pressed Then
          _gameBoard.RotatePiece(x, y, True)
          timeSinceLastInput = 0
        End If
      End If
    End Sub

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 on the game board the mouse was over.

We break the mouse position into X and...

Time for action – letting the player play


  1. Modify the Update() method of Game1.vb, by adding the following before the call to MyBase.Update(gameTime):

    Select Case gameState
      Case GameStates.TitleScreen
        If Keyboard.GetState().IsKeyDown(Keys.Space) Then
          _gameBoard.ClearBoard()
          _gameBoard.GenerateNewPieces(False)
          playerScore = 0
          gameState = GameStates.Playing
        End If
    
        Case GameStates.Playing
          timeSinceLastInput +=
          (CSng(gameTime.ElapsedGameTime.TotalSeconds))
    
          If timeSinceLastInput >= MinTimeSinceLastInput Then
            HandleMouseInput(Mouse.GetState())
          End If
    
          _gameBoard.ResetWater()
    
          Dim y As Integer
    
          For y = 0 To GameBoard.GameBoardHeight
            CheckScoringChain(_gameBoard.GetWaterChain(y))
          Next
    
          _gameBoard.GenerateNewPieces(True)
    End Select

What just happened?

The Update() method performs two different functions, depending on the current gameState value. If the game is in TitleScreen state, Update...

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 code up into classes that represent objects in the game

  • Building a recursive method

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

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

In Chapter 3, Flood Control - Smoothing Out the Rough Edges, 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

  • Visual Basic edition of Kurt Jaegers' XNA 4.0 Game Development by Example. The first book to target Visual Basic developers who want to develop games with the XNA framework
  • Dive headfirst into game creation with Visual Basic and the XNA Framework
  • Four different styles of games comprising a puzzler, space shooter, 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

Description

XNA Game Studio enables hobbyists and independent game developers to easily create video games, and now gives that power to Visual Basic developers. XNA lets you bring your creations to life on Windows, the Xbox 360 and the Windows Phone platforms. The latest release of XNA has added support to Visual Basic and therefore, Visual Basic developers now have the power to give life to their creativity with XNA.This book covers both the concepts and the implementations necessary to get you started on bringing your own creations to life with XNA. It presents four different games, including a puzzler, space shooter, multi-axis shoot 'em up, and a jump-and-run platformer. Each game introduces new concepts and techniques to build a solid foundation for your own ideas and creativity.This book details the creation of four games, all in different styles, from start to finish using Visual Basic and the Microsoft XNA framework. 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 Visual Basic would be needed to kickstart your game development.

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
Estimated delivery fee Deliver to Latvia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Dec 23, 2011
Length: 424 pages
Edition : 1st
Language : English
ISBN-13 : 9781849692403

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Latvia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Dec 23, 2011
Length: 424 pages
Edition : 1st
Language : English
ISBN-13 : 9781849692403

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 €5 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 €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 121.97
Microsoft XNA 4.0 Game Development Cookbook
€41.99
XNA 4 3D Game Development by Example: Beginner's Guide
€41.99
XNA 4.0 Game Development by Example: Beginner's Guide - Visual Basic Edition
€37.99
Total 121.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.8
(10 Ratings)
5 star 80%
4 star 20%
3 star 0%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




LabRat Mar 18, 2013
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very good examples and really like that it addresses visual basic. Hope author comes out with a 3D version for VB also.
Amazon Verified review Amazon
C. Moeller May 02, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
The book is aimed towards beginners starting out in game programming. Visual basic is one of the easier languages to get started in, and XNA is a well known game framework, so it is an excellent place for beginners to start.The book starts out with an introduction to XNA, and how to set it up on your machine for development. The author explains everything he adds to the code, which makes it easy to understand what each addition does.The first game is created in chapter 2, so the author quickly gets into actually creating games fairly quickly, while introducing important concepts such as sprite sheets and tile based games.The following games continue to introduce important concepts, from collision detection to the A* pathfinding algorithm, and even using a map editor to make levels for a side scrolling mario-esque game!I would definitely recommend this book to beginner and intermediate game programmers. The amount of important concepts introduced in this book would give you a great start to developing more advanced games in the future, and the concepts will still be useful for any 3d games. It doesn't matter so much what language you start out programming, just learning the game programming concepts will get you started regardless of what language you eventually choose to develop in.
Amazon Verified review Amazon
Pedro Guida Feb 07, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Based on its C# sibling , this book brings a great introduction to XNA 4.0 for devs that use Visual Basic as their primary language.Targeting beginners, the author introduces useful concepts and techniques applicable to both, game development per se and XNA 4.0, through four games: a puzzler, a space shooter, a multi-axis shoot 'em up and a jump-and-run platformer.All code presented is fully explained by the Author and explanations are written clearly and simple, so each chapter is easy to follow.To wrap it up: fully explained, easy to understand and with four different game examples, the book is a must have for VB devs that want to take their first steps on the XNA world.
Amazon Verified review Amazon
LP Apr 30, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
XNA originally required the novice programmer to learn a few new concepts all at the same time theXNA Framework, .Net, C# together with many programming and maths concepts required in created2D and 3D games. Jumping directly into C# itself was a tall order especially when one already learnsother languages at school / college such as Visual Basic (VB). This is possibly why the most requestedfeature for XNA was to enable support for Visual Basic.This book does not dwell on the pros or cons of C# v VB for development, and assumes that thereader has already made this choice, otherwise why read the book. It is for each novice programmerto decide which programming language is more suited to them and if undecided it may make senseto use this book orientated to VB and compare it with its sister book XNA 4.0 Game Development byExample, orientated to C#. They use the same sample programs and are so a good way to determinewhich is easier to learn for each individual.As a novice programmer the first thing you should do is download the complimentary source codethat is available from the publisher's web site. This book is not a typing tutorial and so it is alwaysbetter to load the code for each sample.As I was already familiar with the actual example programs I skipped through most of their detail,and concentrated mainly on the differences between C# and VB, mainly to fill in my own knowledgeof what had occurred in VB since my last venture with VB6.I continue to like the books editing style with detailed explanations of each step with regularsections of `What just happened?' . This makes it easy to distinguish the stepped explanations fromthe general content for each chapter.I must again highlight the excellent explanations for path finding using the A* algorithm. This topic isessential for every game programmer eventually.Having read the book it failed to convert me from C# to VB, but that was not its objective.If you are a novice programmer and still undecided whether to follow the C# or VB route what betterway than to acquire both the VB and the C# version of this book can decide for yourself whichlanguage suits your existing knowledge.
Amazon Verified review Amazon
Code Monkey Mar 04, 2012
Full star icon Full star icon Full star icon Full star icon Full star icon 5
XNA is a fantastic platform for developing rich, immersive, robust experiences for gamers on Windows, Windows Phone, and Xbox consoles. The platform has been long the domain of C# developers only. That has now changed with the advent of the XNA Game Studio for Visual Basic.This book offers an excellent rundown of the capabilities of Visual Basic on the platform and provides superb step by step examples of how to complete some of the most essential parts of game design.The examples are clear and well thought out and the author does an excellent job of walking the developer through the process. This is done at a high enough level for beginners while still offering enough information and material for developers that have previously worked on the platform.The book's an excellent read and a great tool for learning the platform if you are a VB developer. With the breadth of the examples, it is a fantastic reference tool that will be a good fit for any developers technical library.
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 the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela