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!