Right, before we add all that fancy graphics, we have to prepare our form first. We'll add some additional picture boxes to hold our images. Like the one to hold the firefighter dalmatian doggy, etc… So, add the controls, and modify their properties as shown in the following tables.
PictureBox
- (name):picDoggy
- BackColor: Web > Transparent
- Image: [Load firefighter doggy image]
- Location: 477; 186
- Size: 131; 201
PictureBox
- (name):picSplash
- Anchor:Right
- BackColor: Web > Transparent
- Image: [Load water splash image]
- Location: 45; 81
- Size: 407; 50
- SizeMode: StretchImage
- Visible: False
And now, adjust your form's properties so it'll show the background image:
Form - frmMain
- BackgroundImage: [Load background image]
If you did everything correctly, you should get your game looking quite similar to the one I've made. But we still have to replace our regular buttons with some fancy ones. If you're really going for the 'wow' effect, you can use pictureboxes combined with labels to replace the buttons. So, remove your buttons (select them and click 'Delete') add some more controls to your form:
Note: Our new picture boxes that'll replace the buttons will be called same as the buttons we're replacing. That way, we won't have to change our old code.
PictureBox
- (name):butGame
- BackColor: Web > Transparent
- Image: [Load cloud image]
- Location: 12; 6
- Size: 126; 53
- SizeMode: StretchImage
PictureBox
- (name):butHighScores
- BackColor: Web > Transparent
- Image: [Load cloud image]
- Location: 144; 6
- Size: 126; 53
- SizeMode: StretchImage
PictureBox
- (name):butNG
- BackColor: Web > Transparent
- Image: [Load cloud image]
- Location: 276; 6
- Size: 126; 53
- SizeMode: StretchImage
Now, we'll add some labels to our clouds:
Label
- (name): lblGameCloud
- BackColor: Web >White
- Location: 23; 26
- Size: 107; 20
- Text: New Game
- TextAlign: MiddleCenter
Label
- (name): lblHighScore
- BackColor: Web >White
- Location: 155; 26
- Size: 107; 20
- Text: High Scores
- TextAlign: MiddleCenter
Label
- (name): lblNG
- BackColor: Web >White
- Location: 286; 26
- Size: 107; 20
- Text: New Game
- TextAlign: MiddleCenter
It would be cool if the label inside the picture box would pop-up when the player moves the mouse over the picture box… Here's the code for all three buttons:
private void butGame_MouseEnter
(object sender, EventArgs e)
{
// Set label font to bold:
lblGameCloud.Font = new Font
(lblGameCloud.Font, FontStyle.Bold);
}
private void butGame_MouseLeave
(object sender, EventArgs e)
{
// Set label font to normal:
lblGameCloud.Font = new Font
(lblGameCloud.Font, FontStyle.Regular);
}
private void butHighScores_MouseEnter
(object sender, EventArgs e)
{
// Set label font to bold:
lblHighScore.Font = new Font
(lblHighScore.Font, FontStyle.Bold);
}
private void butHighScores_MouseLeave
(object sender, EventArgs e)
{
// Set label font to normal:
lblHighScore.Font = new Font
(lblHighScore.Font, FontStyle.Regular);
}
private void butNG_MouseEnter
(object sender, EventArgs e)
{
// Set label font to bold:
lblNG.Font = new Font
(lblNG.Font, FontStyle.Bold);
}
private void butNG_MouseLeave(
object sender, EventArgs e)
{
// Set label font to normal:
lblNG.Font = new Font
(lblNG.Font, FontStyle.Regular);
}
To make this code work, go to your form designer window, then go to your properties window, and click on the 'Events' icon (lightning) on the top of the box. Select your new controls, one by one and find events called MouseEnter and MouseLeave. Click on the little dropdown arrow and you'll see our new code method names in the list. I hope you can find and match the right ones… If not, here's a list that shows you how to match the righ stuff.
- Control - Event - EventName
- butGame - Click - butGame_Click
- butGame - MouseEnter - butGame_MouseEnter
- butGame - MouseLeave- butGame_MouseLeave
- butHighScores - Click - butHighScores_Click
- butHighScores - MouseEnter - butHighScores_MouseEnter
- butHighScores - MouseLeave- butHighScores_MouseLeave
- butNG - Click - butNG_Click
- butNG - MouseEnter - butNG_MouseEnter
- butNG- MouseLeave- butNG_MouseLeave
- lblGameCloud - Click - butGame_Click
- lblGameCloud- MouseEnter - butGame_MouseEnter
- lblGameCloud- MouseLeave- butGame_MouseLeave
- lblHighScore - Click - butHighScores_Click
- lblHighScore - MouseEnter - butHighScores_MouseEnter
- lblHighScore - MouseLeave- butHighScores_MouseLeave
- lblNG - Click - butNG_Click
- lblNG - MouseEnter - butNG_MouseEnter
- lblNG- MouseLeave- butNG_MouseLeave
You probably noticed in the table that we added the 'Click' event to our old button code… That's a nice touch in VS.net, that spares us from retyping the code… (or c/p-ing ;) Nice… Hope you did everything right… And one other cool thing is, that we added the same code to our labels and pictureboxes... Before you try the stuff, let's finally add some graphics.
Ok, what next? Obviously, we have to replace those blocks with that nice, round bubbles… So, that's next on our agenda.
So, we're finally here! You had enough time to design your own graphics. Hehe... I know, I know... Your dog ate the memory stick on wich you saved the files... :P Just kidding! Feel free to download the graphics i used for the game. Here's the link:
Link! (*.rar)
Everything is in there!
Take a look at them, and we'll continue in a couple of days!
I'm really sorry that I can't write posts more frequentley. I hope things will improve soon.
Enjoy!
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)