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!). :)
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!
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...