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:
      Public ReadOnly Property PieceType As String
        Get
          Return _pieceType
        End Get
      End Property
    
      Public ReadOnly Property PieceSuffix As String
        Get
          Return _pieceSuffix
        End Get
      End Property

What just happened?

Our new class file begins containing only the class declaration (Public Class GamePiece) and the End Class statements. Inside the class, you have added an array called PieceTypes that gives a name to each of the different types of game pieces that will be added to the game board. There are two straight pieces, four angled pieces, and an empty tile with a background image on it, but no pipe. The array is declared as Shared, because all instances of the GamePiece class will share the same array. A Shared member can be updated at execution time, but all members of the class will see the same changes.

Second, you have declared two integer constants that specify the height and width of an individual playing piece in pixels, along with two variables that specify the array index of the last piece that can be placed on the board (MaxPlayablePieceIndex) and of the fake Empty piece.

Next are four integers that describe the layout of the texture file you are using. There is a one-pixel offset from the left and top edge of the texture (the one-pixel border), and a single pixel of padding between each sprite on the sprite sheet.

Tip

Constants versus numeric literals

Why create constants for things, such as PieceWidth and PieceHeight, and have to type them out when you could simply use the number 40 in their place? If you need to go back and resize your pieces later, you only need to change the size in one place, instead of hoping that you find each place in the code where you entered 40, and change them all to something else. Even if you do not change the number in the game you are working on, you may re-use the code for something else later, as having easily changeable parameters will make the job much easier.

There are only two pieces of information that each instance of GamePiece will track about itself—the type of the piece and any suffix associated with the piece. The instance members _pieceType and _pieceSuffix store these values. We will use the suffix to determine if the pipe that the piece represents is empty or filled with water.

However, these members are declared as private, in order to prevent code outside the class from directly altering the values. To allow them to be read but not written to, we create a pair of read-only properties (PieceType and Suffix), which contain get blocks but no set blocks. This makes these values accessible in a read-only mode to code outside the GamePiece class.

Tip

Visual Basic versus C# - property names

It is a common convention in C# code to create a private member variable of a class with a lowercase first letter and a public property with the same name and an uppercase letter. In the C# version of the GamePiece class, the _pieceType and _pieceSuffix would be named simply pieceType and suffix. In Visual Basic, this would clash with the PieceType and Suffix property names, so the leading underscore (_) is used to differentiate the names.

This naturally leads to the question: what is a property, anyway? In some respects, a property behaves like a variable. It can return a value, and some properties can be assigned values like a variable. Under the hood, though, they are a bit more powerful. When the value of a property is set or checked, code can be executed to compute a return value, validate the stored value, or take any number of other actions. Whenever we want our class to provide data to the outside world, properties provide a method to control how that data is presented and modified, while simple public variables would not. The two properties we use here are declared ReadOnly, meaning we can read the values, but we cannot assign new values to them.

Creating a GamePiece

The only information we need to create an instance of GamePiece are the piece type and, potentially, the suffix.