WPF C# Tutorial – Create Snipe the dummies, a sniper scope shooter game in visual studio
- Subject: WPF C# Tutorials
- Learning Time: 3 hours
Full Source C# Code for the Shoot The Dummy Sniper Game in Visual Studio –
Hope you have followed along carefully during programming this game. If there are issues you can always refer back to this page and see where the code has wrong. All of the codes are selectable and you can try out your own amendments to it and see how it works.
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 for the timer
namespace snipe_the_dummy
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ImageBrush backgroundImage = new ImageBrush(); // Background image holder
ImageBrush ghostSprite = new ImageBrush(); // ghost image holder
ImageBrush aimImage = new ImageBrush(); // aim image holder
DispatcherTimer DummyMoveTimer = new DispatcherTimer(); // timer to move dummy images
DispatcherTimer showGhostTimer = new DispatcherTimer(); // timer for the ghost images
int topCount = 0; // top location counter
int bottomCount = 0; // bottom location counter
int score; // keep score
int miss; // keep misses
List<int> topLocations; // top location lists
List<int> bottomLocations; // bottom location lists
List<Rectangle> removeThis = new List<Rectangle>(); // garbage collector for this game
Random rand = new Random(); // generate random numbers
public MainWindow()
{
InitializeComponent();
this.Cursor = Cursors.None; // hide the mouse cursor
//set up the background image by assigning the imagebrush to the canvas background
backgroundImage.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/background.png"));
MyCanvas.Background = backgroundImage;
//setting up score aim image for the player
scopeImage.Source = new BitmapImage(new Uri("pack://application:,,,/images/sniper-aim.png"));
// setting up the ghost image
ghostSprite.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/ghost.png"));
//set up the dummy moving timer
DummyMoveTimer.Tick += DummyMoveTick;
DummyMoveTimer.Interval = TimeSpan.FromMilliseconds(rand.Next(800, 2000));
DummyMoveTimer.Start();
// set up the ghost animation timer
showGhostTimer.Tick += ghostAnimation;
showGhostTimer.Interval = TimeSpan.FromMilliseconds(20);
showGhostTimer.Start();
// add top location tos to the list these are in pixels
topLocations = new List<int> { 270, 540, 23, 270, 540, 23 };
// add bottom location to the list these are in pixels
bottomLocations = new List<int> { 128, 678, 138, 128, 678, 138 };
}
private void ShootDummy(object sender, MouseButtonEventArgs e)
{
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
MyCanvas.Children.Remove(activeRec); // find the rectangle and remove it from the canvas
score++; // add 1 to the score
if ((string)activeRec.Tag == "top")
{
// if the rectangles tag was top
// deduct one from the top count integer
topCount--;
}
else if ((string)activeRec.Tag == "bottom")
{
// if the rectangles tag was bottom
// deduct one from the bottom count integer
bottomCount--;
}
// make a new ghost rectangle
//width 60 pixels and height 100 pixels
// it will have a tag called ghost and fill will be ghost image
Rectangle ghostRec = new Rectangle
{
Width = 60,
Height = 100,
Fill = ghostSprite,
Tag = "ghost"
};
// once the rectangle is set we need to give a X and Y position for the new object
// we will calculate the mouse click location and add it there
Canvas.SetLeft(ghostRec, Mouse.GetPosition(MyCanvas).X - 40); // set the left position of rectangle to mouse X
Canvas.SetTop(ghostRec, Mouse.GetPosition(MyCanvas).Y - 60); // set the top position of rectangle to mouse Y
MyCanvas.Children.Add(ghostRec); // add the new rectangle to the canvas
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
// Get the x and y coordinates of the mouse pointer.
System.Windows.Point position = e.GetPosition(this);
double pX = position.X;
double pY = position.Y;
// Sets the Height/Width of the circle to the mouse coordinates.
Canvas.SetLeft(scopeImage, pX - (scopeImage.Width / 2));
Canvas.SetTop(scopeImage, pY - (scopeImage.Height / 2));
}
private void ghostAnimation(object sender, EventArgs e)
{
scoreText.Content = "Scored: " + score; // link the score text label to score
missText.Content = "Missed: " + miss; // link the miss text label to miss
// run a foreach loop to check if there are any recntagles present in the canvas
foreach (var x in MyCanvas.Children.OfType<Rectangle>())
{
// if any rectangle has the ghost tag attached to them
if ((string)x.Tag == "ghost")
{
// animate it towards top of the screen
Canvas.SetTop(x, Canvas.GetTop(x) - 5);
// if any ghost makes it to -180 pixels to the top
if (Canvas.GetTop(x) < -180)
{
// add this ghost to the garbage collection
removeThis.Add(x);
}
}
}
// removing its from the scene
// check how many rectangles are in the items move list
// remove them from the list using the for each loop
foreach (Rectangle y in removeThis)
{
MyCanvas.Children.Remove(y);
}
}
private void DummyMoveTick(object sender, EventArgs e)
{
removeThis.Clear(); // clear the garbage collector when it loads
// this for each loop will check if we have any rectangles in this scene, if we do we need to clear it out first
foreach (var i in MyCanvas.Children.OfType<Rectangle>())
{
// see if any present rectangle have the top or bottom tag assigned to them
if ((string)i.Tag == "top" || (string)i.Tag == "bottom")
{
removeThis.Add(i); // add these items to the remove this list
topCount--; // take out 1 from the top count
bottomCount--; // take out 1 from the bottom count
miss++; // add them to miss integer
}
}
// if the top count is less than 3
if (topCount < 3)
{
// run show dummies function
ShowDummies(topLocations[rand.Next(0, 5)], 35, rand.Next(1, 4), "top");
topCount++; // add 1 to the top count
}
// if the bottom count is less than 3
if (bottomCount < 3)
{
// run the show dummies function
ShowDummies(bottomLocations[rand.Next(0, 5)], 230, rand.Next(1, 4), "bottom");
bottomCount++; // add one to the bottom count
}
}
private void ShowDummies(int x, int y, int skin, string tag)
{
// create a new image brush for the dummy background
ImageBrush dummyBackground = new ImageBrush();
// whick ever skin number comes through this function
// it will change the dummy background accordingly
// each number will be monitored and assigned a case to respond appropriately
switch (skin)
{
case 1:
dummyBackground.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/dummy01.png"));
break;
case 2:
dummyBackground.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/dummy02.png"));
break;
case 3:
dummyBackground.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/dummy03.png"));
break;
case 4:
dummyBackground.ImageSource = new BitmapImage(new Uri("pack://application:,,,/images/dummy04.png"));
break;
}
// make a new rectangle
// this recntagle will have the tag passed into this function
// width 80 pixels and height 155 pixels
// the fill colour of the rectnage will be dummy background image
Rectangle newRec = new Rectangle
{
Tag = tag,
Width = 80,
Height = 155,
Fill = dummyBackground
};
Canvas.SetTop(newRec, y); // position the rectangles y position
Canvas.SetLeft(newRec, x); // position the rectangles x position
MyCanvas.Children.Add(newRec); // add the new rectangle to the canvas
}
}
}