WPF C# Tutorial – Create a fun Balloon popping game in visual studio
- Subject: WPF C# Tutorials
- Learning Time: 2 hours
Full Source C# Code for Balloon Popping Game in Visual Studio –
Below is the full C# source for the balloon poppping game, make sure you have followed along accurately and if there if any line showing red highlight under it check it with the code from below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading; // add this line for the timer
namespace Balloon_Pop_Game
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//create a new timer called game timer
DispatcherTimer gameTimer = new DispatcherTimer();
// set initial speed to 3
int speed = 3;
// set initial intervals to 90
int intervals = 90;
// create a new random number generator class
Random rand = new Random();
// a list to remove items from the canvas
List<Rectangle> itemRemover = new List<Rectangle>();
// background image texture class
ImageBrush background = new ImageBrush();
// integer to keep track of different balloon images
int balloonSkins;
// this integer will be used move the balloons left or right slightly
int i;
// missed balloon count integer
int missedBalloons;
// boolean to check if the game is active or not
bool gameisactive;
// score counter
int score;
// create a new media player to link the pop sound to
private MediaPlayer player = new MediaPlayer();
public MainWindow()
{
InitializeComponent();
//start loading the default settings
gameTimer.Tick += gameEngine; // link the timer to the game engine event
gameTimer.Interval = TimeSpan.FromMilliseconds(20); // set timer interval to 20 milliseconds
// set the background image for the canvas
background.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/background-Image.jpg"));
MyCanvas.Background = background;
// run the reset game function
ResetGame();
}
private void canvasKeyIsDown(object sender, KeyEventArgs e)
{
// if the space key is pressed and the game is not active
if (e.Key == Key.Space && gameisactive == false)
{
// run the reset function
ResetGame();
}
}
private void popBalloons(object sender, MouseButtonEventArgs e)
{
// check i the game is active
// this method will stop the player from the clicking the buttons when the game has stopped
if (gameisactive)
{
if (e.OriginalSource is Rectangle)
{
// if the click source is a rectangle then we will create a new rectangle
// and link it to the rectangle that sent the click event
Rectangle activeRec = (Rectangle)e.OriginalSource; // create the link between the sender rectangle
//load the mp3 file to the player URI
player.Open(new Uri("../../files/pop_sound.mp3", UriKind.RelativeOrAbsolute));
player.Play(); // play the mp3 file
MyCanvas.Children.Remove(activeRec); // find the rectangle and remove it from the canvas
score++; // add 1 to the score
}
}
}
private void startGame()
{
// this function will start the game
// first start the timer
gameTimer.Start();
// set missed balloon to 0
missedBalloons = 0;
// set score to 0
score = 0;
// set intervals to 90
intervals = 90;
// change game is active boolean to true
gameisactive = true;
speed = 3; // set speed to 3
}
private void ResetGame()
{
// this function will reset the game and remove any unused item from the canvas
// run loop to find any rectangles in this canvas
foreach (var x in MyCanvas.Children.OfType<Rectangle>())
{
// if found add it to the item remover list
itemRemover.Add(x);
}
// check if there is any rectangles in the item remover list
foreach (Rectangle y in itemRemover)
{
// if found remove it from the canvas
MyCanvas.Children.Remove(y);
}
// clear everything form the list
itemRemover.Clear();
// start the game function
startGame();
}
private void gameEngine(object sender, EventArgs e)
{
scoreLabel.Content = "Score: " + score; // link the score integer to the score label
// deduct 10 from the intervals number
intervals -= 10;
// if interval is less than 1 then we will make new balloons for this game
if (intervals < 1)
{
// first create a new image brush for the balloons called balloomImage
ImageBrush balloonImage = new ImageBrush();
// add 1 to the balloon skins integer
balloonSkins += 1;
// if the skins integer goes above 5 reset back to 1
if (balloonSkins > 5)
{
balloonSkins = 1;
}
// check which skin number is selected and change them to that number
switch (balloonSkins)
{
case 1:
balloonImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/balloon1.png"));
break;
case 2:
balloonImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/balloon2.png"));
break;
case 3:
balloonImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/balloon3.png"));
break;
case 4:
balloonImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/balloon4.png"));
break;
case 5:
balloonImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/files/balloon5.png"));
break;
}
// make a new rectangle called new balloon
// inside this it has a tag called bloon, height 70 pixels and width 50 pixels and balloon image as the background
Rectangle newBalloon = new Rectangle
{
Tag = "bloon",
Height = 70,
Width = 50,
Fill = balloonImage
};
// set the top location of the balloon to 600 pixels so it spawns below the main window
Canvas.SetTop(newBalloon, 600);
// randomly set the left position between these two numbers
Canvas.SetLeft(newBalloon, rand.Next(50, 400));
// add the new item to the screen
MyCanvas.Children.Add(newBalloon);
// set the next interval between these two numbers
intervals = rand.Next(80, 140);
}
//this is the main game loop
// find any rectangles present in this canvas
foreach (var x in MyCanvas.Children.OfType<Rectangle>())
{
// if the item is rectangle and has a tag bloon
if (x is Rectangle && (string)x.Tag == "bloon")
{
// randomly select between two numbers
i = rand.Next(-5, 5);
// move the balloon object towards top of the screen
Canvas.SetTop(x, Canvas.GetTop(x) - speed);
// randomly move the objects left and right position with i integer values
Canvas.SetLeft(x, Canvas.GetLeft(x) - (i * -1));
}
// if the balloon reach top of the screen
if (Canvas.GetTop(x) < 20)
{
// remove them
itemRemover.Add(x);
// add 1 missed integer
missedBalloons++;
}
}
// if you miss more than 10 balloons
if (missedBalloons > 10)
{
gameisactive = false;// set game active to false
gameTimer.Stop(); // stop the timer
// show the message box below
MessageBox.Show("You missed 10 Balloons, press space to restart");
}
// if score if more than 20
if (score > 20)
{
// change the speed to 6
speed = 6;
}
// garbage collection
// remove any item thats been added to the item remover list
foreach (Rectangle y in itemRemover)
{
MyCanvas.Children.Remove(y);
}
}
}
}
When I start the game it works fine but after a few pops the game stops and in the .cs says that there is an exception unhandled “the enumerator is not valid because the collection changed.” in:
foreach(var x in MyCanvas.Children.OfType())
@coco: I had the same problem. My brackets were closing in the wrong place.