Labels:
file,
font,
high score,
i/o,
list,
pad,
read,
sort,
source code,
string,
top list,
write
There's nothing better than prooving to everybody that you're the best! And you certanly can't do that if your score isn't saved. We are now going to make a high score list. For it to work, we'll need a file, that we'll write the scores into. The scores will be consisted of the following: Score, Level, and Player Name. We'll need a new command button to show the list, and a new label to display the results in it. Add them to your game's form, and apply the next properties to them:
Button
- (name): butHighScores
- Location: 144; 6
- Size: 126; 53
- Text: High Scores
Label
- (name):lblHighScoreList
- AutoSize: True
- BackColor: Web > Transparent
- Font: Courier New; 14,25pt; style=Bold
- ForeColor: Web > OrangeRed
- Location: 17; 81
- Size: 0; 22
- Text: [BLANK]
- Visible: False
Ok, and now the code for the button:
// If the High Score list
// isn't visible - show it.
// If it's visible - hide it.
if (lblHighScoreList.Visible == false)
{
// Show High scores.
// We'll read the high scores,
// but won't try to process
// the current score:
// First, hide the game field:
picGameField.Hide();
// Call our function that reads
// the high scores:
HighScore(false);
// Reset the text in our label:
lblHighScoreList.Text = "";
// This is the cool part:
// Strings are so fun! You can
// do just about anything with
// them in C#! Here, we format
// the string with PAD functions.
// Padding means adding characters
// (or spaces) in front (or back)
// of the string. Google for more
// info!
// Format the header line:
lblHighScoreList.Text =
"#".PadLeft(3) + " " +
"Score".PadRight(8) + " " +
"Level".PadLeft(5) + " " +
"Name".PadRight(22) + " " +
"\n\r"; //New line
//Read all highscores from the list:
for (int h = 0; h < ScoreList.Count; h++)
{
int p = h + 1;
lblHighScoreList.Text +=
p.ToString().PadLeft (3) + " " +
ScoreList[h].iScore .ToString().PadLeft
(8, '0') + " " +
ScoreList[h].iLevel .ToString().PadLeft
(5) + " " +
ScoreList[h].sName.PadRight
(22) + " " +
"\n\r"; //New line
}
// Show the filled label:
lblHighScoreList.Visible = true;
}
else
{
// Hide the High Score list,
// and show the game field:
picGameField.Show();
lblHighScoreList.Visible = false;
picGameField.Refresh();
}
But, we're not done yet. We have to give our player some way to input his name, assuming he made it into the top ten... So, add the next controls, and change their properties as shown:
Panel
- (name): IOBox
- BackColor: Web > Transparent
- BorderStyle: FixedSingle
- Location: 301; 6
- Size: 311; 53
- Visible: False
Text Box !!! PUT IT INSIDE IOBox Panel !!!
- (name):txtHS
- BackColor: Web > Tan
- BorderStyle: FixedSingle
- Font: Microsoft Sans Serif; 12pt; style=Bold
- ForeColor: Web >Green
- Location: 3; 22
- MaxLenght: 20
- Size:199; 26
- Visible: False
Button !!! PUT IT INSIDE IOBox Panel !!!
- (name): butIO
- Location: 208; 22
- Size: 100; 26
- Text: Yea!
- Visible: False
Label !!! PUT IT INSIDE IOBox Panel !!!
- (name): lblHS
- Autosize: True
- Font: Microsoft Sans Serif; 9pt; style=Bold
- Location: 0; -1
- Size: 312; 15
- Text: You have a high score! Please enter your name:
- TextAlign: TopCenter
- Visible: False
Ok, and now the rest of the code - put it in private void HighScore(bool bCalculate)!
// Clear the score list:
ScoreList.Clear();
// Read High scores from file:
// We'll use a file named "wGames.hs".
// It's basicaly a normal text file.
FileStream fileR =
new FileStream
("wGames.hs", FileMode.OpenOrCreate);
StreamReader reader =
new StreamReader(fileR);
string sRead;
while ((sRead = reader.ReadLine()) != null)
{
// Read the file line by line.
// The scores in the file are
// ordered from the highest to
// the lowest. A line in the file
// is in the next form:
// SCORE;LEVEL;NAME
// Declare an array of strings,
// and fill it with the parts
// of the high-score line,
// wich we split with the C#
// built in Split() function!
string[] aRead = sRead.Split(';');
// Let's write our scores in a
// struct.
stScores ScoreStruct =
new stScores();
ScoreStruct.iLevel = int.Parse(aRead[1]);
ScoreStruct.iScore = int.Parse(aRead[0]);
ScoreStruct.sName = aRead[2];
// And add the struct to the
// ScoreList:
ScoreList.Add(ScoreStruct);
// Now, we can sort the Score
// List:
ScoreList.Sort(delegate
(stScores s1, stScores s2)
{ return s2.iScore.CompareTo
(s1.iScore); });
}
// Close the file:
reader.Dispose();
fileR.Dispose();
// This code checks if we need
// to process the current score,
// because we use this function
// for both, processing, and just
// showing the high score.
if (bCalculate == true)
{
// If the list contains less than
// ten scores, we add the current
// score in the list automatically.
if (ScoreList.Count > 9)
{
// If the list contains ten or
// more scores, we have to check
// if the current score is high
// enough.
if (ScoreList[9].iScore
< iScore)
{
// We display the HighScore
// entry controls!
IOBox.Visible = true;
lblHS.Visible = true;
txtHS.Visible = true;
butIO.Visible = true;
}
}
else
{
// We don't show the controls
// for high score entry!
IOBox.Visible = true;
lblHS.Visible = true;
txtHS.Visible = true;
butIO.Visible = true;
}
}
And now, add this code to the butIO's click method:
// Put the current score and
// level number in a struct:
stScores NewScore = new stScores();
NewScore.iScore = iScore;
NewScore.iLevel = iLevel;
// Also, put the player name
// in the same struct. If the
// Player didn't enter a name,
// just call him 'J. Doe'.
// (we don't know if J. stands
// for John or Jane :)
if (txtHS.Text.Trim().Length == 0)
{
NewScore.sName = "J. Doe";
}
else
{
// We use ; as a delimiter in
// our high score file. So, if
// the user would enter it in
// the text box - it would crash
// our game. That's why we'll
// replace all the ; with commas.
txtHS.Text.Replace(';', ',');
NewScore.sName = txtHS.Text.Trim();
}
// Add the struct to the list:
ScoreList.Add(NewScore);
// Sort the list:
ScoreList.Sort(delegate
(stScores s1, stScores s2)
{ return s2.iScore.CompareTo
(s1.iScore); });
// Write the list back into the
// file. We'll overwrite the old
// file.
StreamWriter writer = new StreamWriter("wGames.hs", false);
// See how many scores we have
// to save to the file. If we
// have more than ten scores
// (full list + new score),
// then save just the top
// ten scores!
int lc = ScoreList.Count;
if (lc > 10) lc = 10;
// Write scores to the file,
// line by line!
for (int w = 0; w < lc; w++)
{
writer.WriteLine
(ScoreList[w].iScore.ToString()
+ ";" +
ScoreList[w].iLevel.ToString()
+ ";" +
ScoreList[w].sName);
}
writer.Dispose();
// And hide the dialog after
// saving the score:
lblHS.Visible = false;
txtHS.Visible = false;
butIO.Visible = false;
IOBox.Visible = false;
And to make this work, we'll have to add a couple of global variables and stuff...( Look at the top of your code, remember?)
//List that holds score structs
List<stScores> ScoreList
= new List<stScores>();
//Struct that holds scores
struct stScores
{
public int iScore;
public int iLevel;
public string sName;
}
Cool? Ok, test your game. It might just work! ;o)
Right! The game's fully functional now (= I hope =). And now comes the 'fun' part - design! :) (as I later found out - not so fun, because I'm 100% graphically challenged)... :c)
Ok, we programmed almost everything that I wanted to see in our gameplay. But this tutorial is far from over. You remember the game screenshot from the first chapter? Our game doesn't look anything like that... In the next few chapters we'll add some practical functions to our game, like 'Pause' button, 'High Score' list, and then we'll move on to the decoration!
Almos every game has a 'Pause' button. It's almost normal that you can't play any game without interuption. Maybe your wife sends you to the store to fetch some ingredients for lunch, or your two-year-old starts pulling the mouse out of your hand, or something else comes in your way... In every case, you don't want your game to go on... So, to satisfy our players, we'll add a pause button. Well, not actualy add - we'll just use our existing 'New Game' button, and programatically make it a multifunctional 'gadget'.
Ok, now, we'll update our code to give our game/pause button the funcionality that it needs. Basically, we'll just stop our timer when the user clicks on the button, and start it again when the user clicks 'Continue'. We won't add a new button for the 'Continue' command. We'll use our current 'Pause' button to do this...
Here's the code:
(overwrite your existing 'GameButton_Click' code!)
if (butGame == "New Game")
{
//NEW GAME
picGameField.Show();
picGameField.Refresh();
NewGame();
butGame.Text = "Pause";
}
else if (butGame.Text == "Pause")
{
//GAME PAUSED
Game.Stop();
picGameField.Visible = false;
lblDisplay.Text = "Game Paused";
lblDisplay.Visible = true;
butGame.Text = "Continue";
}
else
{
//CONTINUE GAME
picGameField.Show();
butGame.Text = "Pause";
picGameField.Visible = true;
Game.Start();
butNG.Visible = false;
}
You probably noticed that we hide the game field when the player clickes 'Pause'. That's because we don't want our players to cheat, and have extra time to plan their moves... Wicked, right? ;)
Now, add another button to the game, and apply it's properties:
Button
- (name): butNG
- Location: 276; 6
- Size: 126; 53
- Text: New Game
This one is going to offer our player the possibility to start a new game. Let's add some code to it. Double click on the new button, and put this code there:
//NEW GAME
picGameField.Show();
picGameField.Refresh();
NewGame();
butGame.Text = "Pause";
butNG.Visible = false;
Ok, let's go on - in the next chapter we'll add a High Scores list to our game. Just so our players can brag about their achievements, and to give them a little bit of motivation for playing the game (if they don't hold the #1 spot on the list!). :)
To make things a little interesting, we'll give the player bonuses after he completes each level. I've thought of two bonuses: One that is awarded for empty columns, and one that is awarded on top, if there are no blocks left on the game field. To calculate the 'Empty Column Bonus' I used this formula: Level * # of Empty Columns * 100. For the second bonus, I used this formula: Level * 1000. So, If a player manages to clear all block in level 4, he would recieve (4*15*100) 6000 points from the Empty Column Bonus, and additional (4*1000) points from the Cleared Level Bonus. That's 10000 points! Nice! To show the player how many points he was awarded, we'll use our existing label (lblDisplay). And we'll pause the game for a few seconds between the levels. In the end, we'll create a method to switch us between levels. Ok, enough talking.
Let's start coding!This is the code that goes into the LevelScore() method:
// A variable for holding
// TEMPORARY empty column
// bonus:
int iColBonus = 0;
//Stop the game play...
Game.Stop();
// Calculate the bonus
// for empty columns
// Go trough all columns:
for (int c = 0; c < iWidth; c++)
{
// If the column is empty,
// increase empty column
// bonus. The column is
// empty whene there's no
// block in the lowest field.
// (Since we have gravity)
if (Field[iHeight - 1, c] == 0)
{
// You can play with this
// code to adjust how many
// points are awarded for
// every empty column:
iColBonus += (100 * iLevel);
}
}
// Add the empty column
// bonus to the total
// score, and show it:
iScore += iColBonus;
lblScore.Text = iScore.ToString();
// Calculate the bonus for
// cleared level :)
// (Mission impossible)
// Temporary variable:
int iLvlClrBonus = 0;
if (iColBonus ==
iWidth * (100 * iLevel))
{
// Code that defines
// and shows the bonus:
iLvlClrBonus = iLevel * 1000;
iScore += iLvlClrBonus;
lblScore.Text = iScore.ToString();
}
// Inform the user that
// the level is over.
lblDisplay.Text = "Level Complete!";
lblDisplay.Visible = true;
this.Refresh();
// Show bonuses,
// if they exist:
if (iColBonus > 0)
{
// Pause 2 seconds:
System.Threading.Thread.Sleep(2000);
// Display first bonus:
lblDisplay.Text = "Empty Column Bonus: "
+ iColBonus.ToString();
this.Refresh();
}
if (iLvlClrBonus > 0)
{
// Pause 2 seconds:
System.Threading.Thread.Sleep(2000);
// Display second bonus:
lblDisplay.Text = "Clear Level Bonus: "
+ iLvlClrBonus.ToString();
this.Refresh();
}
// Pause 2 seconds:
System.Threading.Thread.Sleep(2000);
// Reset the display
// label, and hide it.
lblDisplay.Visible = false;
lblDisplay.Text = "GAME OVER!";
So, let's move to the next chapter and see how we can play with the parameters of our gameplay to make things more interesting.
Update: I finally managed to sort out the feed for this site. (Before, the feed for this site was copyed from my other blog... uh...)
Almost all games have levels. As the player advances, the game becomes more and more difficult. We'll do just that. We'll speed up our gameplay from level to level, and add a new color to the blocks every three or four levels... That should spice things up nicely... Uh! Oh! Another idea: let's increase the number of columns from level to level! So, that would mean that the player needs to survive 15 columns in the first level to move on, 16 in the second, and so on... Our game will not have a finall level. If the player is skilled enough, he could play trough an infinite number of levels. But hey, that's almost impossible. Reaching level 10 will be almost like winning in a lottery ;) Hehe...
So, when the player starts a new game we should reset the level count, score, speed, colors.. So we'll fill our 'NewGame' method.
// Reset the level and
// score value, and the
// number of colors in the game:
iLevel = 0;
lblLevel.Text = iLevel.ToString();
iScore = 0;
lblScore.Text = iScore.ToString();
iColor = 3;
iColors = 0;
// Reset the game speed
Game.Interval = 4000;
// We don't have the IOBox yet,
// so, the next line is commented
// out:
// IOBox.Visible = false;
lblDisplay.Visible = false;
NewLevel();
Now, add a new label to the form. Here are the settings:
Label
- (name): lblLevel
- BackgroundColor: Web > Transparent
- Location: 555;81
- Font: Microsoft Sans Serif; 9,75pt; style=Bold
- Text:1
And here's the code for going from level to level.
(Put it in the NewLevel() method)
//Increase the level number.
iLevel++;
// Increase the number of
// columns needed to complete
// the level. You can play
// with this code to make the
// game harder or easier.
iColumns = iWidth - 1 + iLevel;
// Reset the column count.
iColumn = 0;
// Increase the number of colors.
// But only to 10. (because we
// didn't prepare more colours in
// our DrawField method)
if (iColor < 10)
{
// Do it every three levels...
// The number '3' in the next
// line tells the game how
// many levels to skip before
// adding a new color:
if (iColors == 3)
{
iColor++;
iColors = 0;
}
else
{
iColors++;
}
}
// Speed up the game.
// We speed it up for 50
// miliseconds from level
// to level. This, probably,
// will stay unnoticed by
// the player. But you can
// change this to increase
// the difficulty.
if(iLevel > 1 &&
Game.Interval > 1500)
{
Game.Interval =
Game.Interval - 50;
}
// Display level text
lblLevel.Text =
iLevel.ToString();
// Create our new level's
// game field (empty):
CreateField();
// And the first column:
CreateNewColumn();
// Show it on the screen:
Redraw();
// Start the game:
Game.Start();
And the last thing is to change your 'New Game' button's code to this:
NewGame()
In the next chapter, we'll add some nice bonuses, that'll show between levels, and give the player to 'breathe' for a second or two... Ok, moving on!
Every game has a way to put a value to the player's effort. In racing games that's done with time (in most cases). In tycoon games, that would be done with money. In our game, we'll just use numbers. So how should we evaluate our players effort? First of all, we have to give him points for every block he destroys. We could make our game give him more points with every new level, and some extra points for the number of different block colors for that level. And some extra scoring math: We could make every block color more valuable... So, let's start with adding a new label to our form, so we could display the score to the player.
The score label properties:
Label
- (name): lblScore
- BackgroundColor: Web > Transparent
- Location: 555;65
- Font: Microsoft Sans Serif; 9,75pt; style=Bold
- Text: 0
Then, add this code to your project:
(put it in the DoTheScoreMath() method.)
// We'll process the score only
// if there's multiple blocks
// in the 'Connected List'.
if (ConnectedList.Count > 1)
{
// I've declared some
// variables to hold
// some values I intend
// on using to calculate
// the score.
int a = ConnectedList.Count;
int b = iLevel;
int c = iColor;
int d = ConnectedList[0].iFieldColor;
// Scoring formula...
// You can play with it
// as you like :)
int e = a * (b + c) * d;
// Just don't forget to
// add it to the total
// score:
iScore += e;
}
// Oh, and to be a little
// naughty, we'll substract
// a point for every click
// the user makes...
// BUAHAAHAAHHAAAAA!
iScore--;
// Display the total score:
lblScore.Text = iScore.ToString();
Now, add the call in the 'picGF_MouseClick' method, after the existing code:
DoTheScoreMath()
Done? Cool! Ok, what now? Levels would be cool... Right, then! Next chapter: Levels!
So, our game is almost playable… Well, it is, but there's a lot of stuff to add… Like, random blocks appearing on the game field. The game I 'borrowed' the idea from, had these blocks apearing at radnom time intervals and random places on the game field… And those fields were cool, because, sometimes, they helped to clear you some additional blocks, and sometimes, they filled that valuable empty columns… Ok, back to the drawing board. Litteraly. Here are two examples, first one that shows when the block is helpful, and another one wich shows when it's not that helpful.

Take a look at the picture. The player has only two empty columns left. Let's think about the next situaion:
a) Let's imagine that in this moment, our game 'spawns' a red field at [4,5]. That would help the player, since he would be able to clear that red field, and the field one block to the right. (the one under [5,4]). The result would be - three empty columns.
b) If we would spawn a blue field at [4,5] - that wouldn't affect the player a lot - he would clear the field, and the blue one on the left. The result would be the same: Two empty columns.
c) If we wolud spawn a green field at that location, that would be the worst case scenario for the player. He would be stuck with only one empty column.
Looking at the Field[5,4], the best thing for the player would be, if we created a red block there. In that case, he could empty the #5 column. Spawning a green block wouldn't make a big difference. When the columns would be moved to the right, the green fields could be cleared. Creating a blue field there would be the worst thing for the player, but that wouldn't mean any disadvantages for him. The empty column count would stay the same.
So, the code for creating a 'random' block:(Put it in the DropBlock() method)
// Once again, we'll use the
// random function. We'll
// generate a random color,
// and a random position for
// our new block.
Random Rndm = new Random();
// Increasing the random range
// decreases the chance to drop
// the block.
int R = Rndm.Next(1, 3);
switch (R)
{
case 1:
// Drop the block!
// Generate the position:
int RX = Rndm.Next(iHeight - 1);
int RY = Rndm.Next(iWidth - 2);
// We dont allow the new block to
// spawn in the last column - so
// we don't cause possible gameover's ;)
// We have to see if the field is empty...
// So we don't overwrite some other field.
// This also affects the possibility
// of creating a random block...
if (Field[RX, RY] == 0)
{
// Fill the block with a random
// color;
Field[RX, RY] =
Rndm.Next(1, iColor + 1);
// Make it fall down...
GoGravity();
}
break;
default:
break;
In the next chapter, we'll make a score method, so we can let the player know how succesful he was...
Uhm, I admit – I lost a whole day to figure this stupid stuff out. And in the end, i ended up with just a few lines of code. It's true that simplicity is the best way. And after writing, like, fifty lines of code that didn't work, i decided to delete it, and to start over. Basically, I took every single block in the game, and checked if it's floating. If it was, I moved it down… This would be the result:

This is the code that goes in the GoGravity() method:
// So, bassicaly, i just use
// a couple of loops to go trough
// all the fields.
// Looping through columns:
for (int s = 0; s < iWidth; s++)
{
// Looping through rows:
for (int l = 0; l < iHeight; l++)
{
for (int v = iHeight - 1; v > 0; v--)
{
// In every column, I start
// checking from the bottom.
if (Field[v, s] == 0)
{
// If the field is empty, I
// drop the field above it
// down one block.
Field[v, s] = Field[v - 1, s];
Field[v - 1, s] = 0;
}
}
}
}
// And to show the changes,
// I call the Redraw() method:
Redraw();
And this is the code that goes into the Redraw() method:
//Drawing our field and grid:
DrawGrid()
DrawField()
In our game, we'll use the mouse as an input device. Player will be able to click anywhere in the game field, and we'll have to figure out if he clicked a block, or an empty field. If the player clicks on the block, we'll have to check if it's connected with any other block of the same color, and we'll have to destroy the blocks if so. And to add a little feature, we'll take away one point for every mouse click. (Wich reminds me… We'll have to make a score counter, real soon.) So, how the hell can we find out where the user clicked? Lucky for us, the Picture Box in wich we draw our game field, has a MouseClick event. So, we'll use it to see if the user clicked anywhere on the game field. But how to find out on what block the user clicked? A little basic math will help us solve this problem. We already have defined that the block field is 32 pixels in width/height. And lucky for us, VS.net can give us the coordinates of the mouse pointer on the screen, and in relation to the clicked object. That means, that VS will give us the distance from the top and left borders of the picture box, measured in pixels. So, those are the ingreedients. Let's mix them all together and see how they work. First of all, go to your design window, select the Picture Box, and then, go to your Properties window. Just above the properties list ther is a little icon of lightning. Click on it, and you'll see the events list. Find the MouseClick event, and double-click on it's name. This should give you the code editor window with the method already in place. Here's the code for it:
// We find the X and the Y coordinate of
// the mouse using the mouse event arguments
// (called 'e'). We'll store them into some
// variables. Note, how we switched X and Y's
// place – that's because we declared our game
// field in the opposite way – X for height
// and Y for width. I know… Goofy…
int mx = e.Location.Y;
int my = e.Location.X;
// The next step is to divide the mouse
// coordinates with the block/field size,
// so we'll get the coordinates of our field.
decimal x = mx / iFieldSize;
decimal y = my / iFieldSize;
/ And to round them up (since they came
// back as numbers with decimals) we
// convert them right back into intigers.
// Not to mention that we need them as
// integers, to define our fields.
int ix = (int)x;
int iy = (int)y;
This code will give you exact coordinates of the block player clicked. Ok, what's next? Obviously, we'll have to see if the block player clicked, is actualy connected to other blocks of the same color. And we'll do just that – in the next chapter.
When we wrote the code for our CreateField() method, we didn't write any code for displaying the field to the user. We'll do it in this chapter. We'll take a look at graphic programming, GDI+… So, let's fill our DrawField() method. Here's the code – go trough it, read the comments (the green stuff), and hopefully, you'll get it. :) I did write a lot of comments. I hope they help.
// Define a Brush – an object that will
// hold the color value for our Game
// Field background.
Brush Background = Brushes.PowderBlue;
// We want to show our field inside the
// Picture Box, so we create a graphich
// object inside our Picture Box.
Graphics gField = picGameField.CreateGraphics();
// We'll go trough all of our fields, and we'll
// display them one by one (taking into consideration
// the color value each field contains). We have 150
// fields, so, we'll do this with the help of two loops.
// It woud be painfull to do it manually.
// First loop that is going trough every line.
for (int v = 0; v <>
{
// Second loop – this one is going
// trough every column.
for (int s = 0; s < iWidth; s++)
{ // We define a small rectangle, for
// every field in our game field. We'll
// use the variable that contains the
// rectangle's width/height. If you
// remember, we defined it in our first
// lines of code.
Rectangle rtgField = new Rectangle
(s * iFieldSize, v * iFieldSize,
FieldSize, iFieldSize);
// First of all, we'll fill our rectangles
// with our background color.
gField.FillRectangle(Background, rtgField);
// And now, we'll fill the field with the color
// that is defined with the fields value.
switch (Field[v, s])
{
case 0:
// Draw empty field...
break;
case 1:
// I've decided that color #1 is Blue. So, if
// the field holds a value of 1 – We'll color it
// blue. And we'll do the same for all
// other colors.
gField.FillRectangle(Brushes.Blue, rtgField);
break;
case 2:
// If the field contains value 2:
// we'll fill it red.
gField.FillRectangle(Brushes.Red, rtgField);
break;
case 3:
// If the field contains value 3:
// we'll fill it green.
gField.FillRectangle(Brushes.Green, rtgField);
break;
case 4:
// If the field contains value 4:
// we'll fill it yellow.
gField.FillRectangle(Brushes.Yellow, rtgField);
break;
case 5:
// If the field contains value 5:
// we'll fill it purple.
gField.FillRectangle(Brushes.Purple, rtgField);
break;
case 6:
// If the field contains value 6:
// we'll fill it black.
gField.FillRectangle(Brushes.Black, rtgField);
break;
case 7:
// If the field contains value 7:
// we'll fill it orange.
gField.FillRectangle(Brushes.Orange, rtgField);
break;
case 8:
// If the field contains value 8:
// we'll fill it gray.
gField.FillRectangle(Brushes.Gray, rtgField);
break;
case 9:
// If the field contains value 9:
// we'll fill it dark blue.
gField.FillRectangle(Brushes.DarkBlue, rtgField);
break;
case 10:
// If the field contains value 10:
// we'll fill it pink.
gField.FillRectangle(Brushes.Pink, rtgField);
break;
default:
// If our program comes to this point of the code,
// something's gone wrong! ;) XD
break;
}
}
}
Now, you're just a few steps away from seeing it on the screen. Go back to your Design View by clicking the tab 'frmMain.cs [design]' on top of the code window. Double click on the 'New Game' button, and you should wind up right back in the 'code' window. But, this time, you'll see some extra lines of code that were generated by the VS.net. The new lines are:
private void butGame_Click(object sender, EventArgs e)
{
}
Add this line of code in between the two curly brackets:
DrawField();
And run your game! (Click on the green 'Play' button in your toolbar). Click on the button, and you should see this:

In the next chapter: We'll fill our CreateGrid() function, and play a little with our blocks... :)