Building the Soccer Program

You now have all the skills you need to build the soccer game introduced at the beginning of the chapter. The game might appear complex if you look at the entire thing at once, but when you break it into its constituent parts, the soccer game isn’t nearly so intimidating.

Setting Up the Variables

As usual, the variables tell you a lot about the program. The Soccer program features a large number of variables declared at the form level, but they are not tricky.

Variables about the Players

The first group of variables is used to give names to the various positions:

//set up constants for players
private int GOALIE = 0;
private int FULLBACK = 1;
private int HALFBACK = 2;
private int WING = 3;
private int CENTER = 4;
private int SHOT = 5;

//array for player names
private string[] playerName = {
  "Goalie",
  "Fullback",
  "Halfback",
  "Wing",
  "Center",
  "Shot"
};

Many times throughout the game code, it is necessary to determine which player you’re talking about. Rather than memorize that the goalie is player 0 and the shot (opposing goal) is player 5, I created special variables to hold these names. The use of all uppercase is traditional when you create a variable like this, which you don’t intend to change throughout the program. You will see how useful these variables are later on as you read through the code.

Likewise, having a string array of strings associated with an array is sometimes handy so that you can easily tell the user what’s going on. The playerName array will typically be used when I want to tell the user something about a player.

Game Management Variables

The next batch of variables is used to control the general flow of the game. These variables are the lifeblood of the game:

//primary game variables
private int playerScore = 0;
private int oppScore = 0;
private int timeLeft = 600;
private int currentPlayer = GOALIE;
private int nextPlayer = FULLBACK;

//data structure for likelihood of shot
private double[,] shotChance =
{{-1, .8, .6, .4, .1, .01},
 {.8, -1, .8, .6, .4, .02},
 {.8, .8, -1, .8, .6, .03},
 {.8, .8, .8, -1, .8, .04},
 {.8, .8, .8, .8, -1, .2},
 {.8, .8, .8, .8, .8, -1}};

The first batch of variables in this group holds typical game variables, such as the player and opponent score, time left in the game (in 10ths of a second), which player currently has the ball, and which player is set to receive the ball. Notice the use of GOALIE and FULLBACK. Because I set these variables earlier, I could use them here to make my intentions much clearer than if I’d just put the numbers 0 and 1.

The Picture Box Arrays

The players zipping around on the field are actually picture boxes. These picture boxes are the trickiest part of the game because there are so many of them. To manage them one at a time would be crazy, so I built two arrays. You can make an array out of any sort of variable, including picture boxes. Of course, the Visual Designer does not support placing arrays of controls. I’ll have to place them by hand, but it’s not difficult, as you will see:

//custom picture box arrays for players
private PictureBox[] picPlayer = new PictureBox[6];
private PictureBox[] picOpp = new PictureBox[5];

Notice that I made two arrays. The picPlayer array deals with the players that the user can click (all the players on the yellow team and the red goalie). The picOpp array contains picture boxes that handle all the players on the red team except the red goalie.

Note that the distinction between the player and opponent arrays is not which team the picture box represents. The red goalie is part of the picPlayer array because it shares a lot of functionality with the players on the yellow team. It can be clicked, and it can be a target to shoot at. None of the other red teams need to respond to click events, and they don’t do anything but move around randomly. The picture boxes that need to respond to events are stored in one array (picPlayer), and those that do not need to respond to events are stored in the other array (picOpp).

The Controls Built with the Form Designer

Building visual controls with the Form Designer is much easier, so I built everything but the picture box arrays, using the designer:

//controls built by designer
private System.Windows.Forms.Label lblAnnounce;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Label lblTime;
private System.Windows.Forms.Label lblPlScore;
private System.Windows.Forms.Label lblOppScore;
private System.Windows.Forms.ImageList myPics;
private System.Windows.Forms.Panel pnlField;
private System.ComponentModel.IContainer components;

The lblAnnounce label delivers a play-by-play account of the game. It announces each pass and shot, helping the user figure out what’s going on in the game.

The game features a standard timer named lblTime. The timer’s interval is set to 100 milliseconds, which means that the game runs at 10 frames per second.

The lblPlScore and lblOppScore labels are used to display the player and opponent scores, respectively.

The program features an ImageList control named myPics, which contains seven images (even though I didn’t use them all in the final game). The images include a yellow player without the ball, a yellow player with the ball, a red player without the ball, a red player with the ball, a yellow goalie and red goalie, and a large red square I used when debugging. Figure 8.14 shows the various images associated with the image list control.

Figure 8.14. The images stored in the image list control.


That large red square turned out to be handy, even though I didn’t include it in the final game. At one point, I had a player just sitting there, not moving. I couldn’t figure out which player it was, so I was unsure how to fix it. One by one, I set the image of each player to the red box and ran the program. After the offending player was set as the red box, I knew which player was having trouble, and I found the problem in the code. Sometimes you have to be inventive in your debugging strategies.

The field itself is a panel, with an image of a soccer field attached. I added all the player picture boxes directly to the panel rather than to the form itself because the panel’s dimensions are a handy way to determine the field's borders. All the other controls (the labels for timing and score) are added to the form itself.

Examining the Constructor

The Soccer program is heavily dependent on custom controls. You might expect a lot going on in the constructor, and you’d be right. However, when you look at the constructor code, you will find it very sparse:

public frmSoccer()
{
   //
   // Required for Windows Form Designer support
   //

   InitializeComponent();
   setupPlayers();
   setupOpp();
   setupGoalies();

} // end constructor

There is so much work for the constructor to do that I decided to break it into smaller sections and send off some of the work to methods. (Encapsulation! I love encapsulation!) This makes it very clear what the big picture assignments are in the constructor and enables you to separate the strategic problem (what kinds of things have to happen in the constructor) from the tactical problems (such as how you set up each picture box array). As you can see, the constructor has four major jobs.

The first is to call InitializeComponent(), which manages all the components created in the Visual Designer. Even though I built some controls by hand, calling InitializeComponent() is still important. If you’re going to add other code to the constructor, that code should come after the InitializeComponent() call.

All the other jobs in the constructor involve setting up the picture box arrays. The array of clickable picture boxes has to be set up. The setupPlayers() method will handle this chore. The opponents have to be set up as well. Their setup is a little different, so it will be handled in a different method, named setupOpp(). Finally, the two goalies have slightly different behavior than the other picture boxes, so they need their own setup routine.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.204.0