- XNA 4.0 Game Development by Example Beginner's Guide(Visual Basic Edition)
- Kurt Jaegers
- 843字
- 2021-08-20 15:50:37
Time for action – build a GamePiece class - declarations
- Switch back to your Visual Studio window if you have your image editor open.
- Right-click on the Flood Control project in Solution Explorer and select Add | Class….
- Name the class
GamePiece.vb
, and click on Add. - 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 = ""
- 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.