Friday, January 11

Snake Game in WPF C#

Download Complete Soulution Here: Snake Game
Screen Shots:

Splash Screen


Menu Window


Source Code: XAML


<Window x:Class="WpfApplication2.MenuWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MenuWindow" Height="474" Width="500" WindowStyle="None" AllowsTransparency="True" Background="{x:Null}" WindowStartupLocation="CenterScreen" Icon="/WpfApplication2;component/image/Snakeicon.png">
    <Grid>
        <Ellipse Height="201" HorizontalAlignment="Left"  Visibility="Hidden" Margin="125,136,0,0" Name="ellipse1" VerticalAlignment="Top" Width="313" StrokeThickness="3" Opacity="1">
            <Ellipse.Effect>
                <DropShadowEffect BlurRadius="50" Color="Green" />
            </Ellipse.Effect>
            <Ellipse.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF0C6155" Offset="1" />
                    <GradientStop Color="#FF85E0E7" Offset="0" />
                    <GradientStop Color="#FF176382" Offset="1" />
                </LinearGradientBrush>
            </Ellipse.Fill>
            <Ellipse.Stroke>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF176382" Offset="0" />
                    <GradientStop Color="#FF85E0E7" Offset="1" />
                </LinearGradientBrush>
            </Ellipse.Stroke>
        </Ellipse>
        <Image Height="313" Opacity="0" Source="image\snake.png" MouseDown="image1_MouseDown" HorizontalAlignment="Left" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="387" Margin="51,19,0,0" >
            <Image.Effect>
                <DropShadowEffect />
            </Image.Effect>
        </Image>
        <Label Content="New Game" Height="28" HorizontalAlignment="Left" Cursor="Hand" FontWeight="Bold" MouseDown="newGameBtn_MouseDown" FontFamily="Chiller" Margin="239,149,0,0" Name="newGameBtn" VerticalAlignment="Top" Width="83" FontSize="20" Foreground="#FF041A1A" FontStyle="Normal" FontStretch="Condensed" Opacity="1" Visibility="Hidden">
            <Label.Effect>
                <DropShadowEffect />
            </Label.Effect>
        </Label>
        <Label Content="High Scores" MouseDown="label1_MouseDown" FontFamily="Chiller" FontWeight="Bold" Cursor="Hand" Height="28" HorizontalAlignment="Left" Margin="239,183,0,0" Name="label1" VerticalAlignment="Top" Width="83" FontSize="20" Foreground="#FF041A1A" FontStyle="Normal" FontStretch="Condensed" Opacity="1" Visibility="Hidden">
            <Label.Effect>
                <DropShadowEffect />
            </Label.Effect>
        </Label>
        <Label Content="Exit" Cursor="Hand" FontFamily="Chiller" FontWeight="Bold" Height="28" HorizontalAlignment="Left" Margin="257,213,0,0" MouseDown="ExitBtn_MouseDown" Name="ExitBtn" VerticalAlignment="Top" Width="39" FontSize="20" Foreground="#FF041A1A" FontStyle="Normal" FontStretch="Condensed" Opacity="1" Visibility="Hidden">
            <Label.Effect>
                <DropShadowEffect />
            </Label.Effect>
        </Label>
        <Label Content="Snake Game v 1.0" Height="Auto"  FontWeight="Bold" FontFamily="Chiller" FontSize="34" HorizontalAlignment="Left" Margin="185,106,0,0" Name="label2" VerticalAlignment="Top" Width="Auto" ForceCursor="False" Visibility="Hidden" Opacity="1" Foreground="#FF03384B">
            <Label.Effect>
                <DropShadowEffect />
            </Label.Effect>
        </Label>
        <Image Height="83" Source="image\Snakeicon.png" MouseDown="image2_MouseDown" Cursor="Hand" MouseLeave="image2_MouseLeave" MouseEnter="image2_MouseEnter" HorizontalAlignment="Left" Margin="204,115,0,0" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="92" >
            <Image.Effect>
                <DropShadowEffect BlurRadius="30" />
            </Image.Effect>
        </Image>
        <Image Height="57" Opacity="0" Source="image/InfoTag.png" HorizontalAlignment="Left" Margin="95,59,0,0" Name="tagInfoimg" Stretch="Fill" VerticalAlignment="Top" Width="257" />
        <Label Content="Developers : Umair Baig" Height="28" HorizontalAlignment="Left" Margin="179,204,0,0" Name="label3" VerticalAlignment="Top" Width="157" FontWeight="Bold" FontFamily="Shruti" Foreground="White" Opacity="0.7">
            <Label.Effect>
                <DropShadowEffect BlurRadius="30" />
            </Label.Effect>
            <Label.BorderBrush>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="White" Offset="1" />
                </LinearGradientBrush>
            </Label.BorderBrush>
            <Label.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF4B81C3" Offset="0" />
                    <GradientStop Color="#FF031F47" Offset="1" />
                </LinearGradientBrush>
            </Label.Background>
        </Label>
    </Grid>
</Window>


C# Code:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MenuWindow.xaml
    /// </summary>
    public partial class MenuWindow : Window
    {
        public MenuWindow()
        {
            InitializeComponent();   
        }

        private void newGameBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            WpfApplication1.Window1 gameWindow = new WpfApplication1.Window1();
            gameWindow.Show();
            this.Close();
        }

        private void ExitBtn_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.Close();
        }
        private void image1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }
        private void image2_MouseEnter(object sender, MouseEventArgs e)
        {
            DoubleAnimation setImageOpacity = new DoubleAnimation();
            setImageOpacity.To = 1;
            setImageOpacity.From = 0;
            tagInfoimg.BeginAnimation(OpacityProperty, setImageOpacity);
        }

        private void image2_MouseLeave(object sender, MouseEventArgs e)
        {
            DoubleAnimation setImageOpacity = new DoubleAnimation();
            setImageOpacity.To = 0;
            setImageOpacity.From = 1;
            tagInfoimg.BeginAnimation(OpacityProperty, setImageOpacity);
        
        }

        private void image2_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // Set opacity of Label Snake Game v1.0

            label2.Visibility = System.Windows.Visibility.Visible;
            image2.Visibility = System.Windows.Visibility.Visible;
            ellipse1.Visibility = System.Windows.Visibility.Visible;
            newGameBtn.Visibility = System.Windows.Visibility.Visible;
            ExitBtn.Visibility = System.Windows.Visibility.Visible;
            label1.Visibility = System.Windows.Visibility.Visible;

            DoubleAnimation setOpacity = new DoubleAnimation();
            setOpacity.To = 0;
            setOpacity.From = 1;
            setOpacity.RepeatBehavior = RepeatBehavior.Forever; // it will do animation forever.
            label2.BeginAnimation(OpacityProperty, setOpacity);


            // set opacity of snake image.

            DoubleAnimation setImageOpacity = new DoubleAnimation();
            setImageOpacity.To = 1;
            setImageOpacity.From = 0;
            image1.BeginAnimation(OpacityProperty, setImageOpacity);




            image2.Visibility = System.Windows.Visibility.Hidden;
            label3.Visibility = System.Windows.Visibility.Hidden;
        }

        private void label1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // High Score File Reading 
            // File is placed at Debug Directory
            string[] readFromFile = File.ReadAllLines("Highscore.txt"); // Data Reading from existing file. File is class and ReadAllLines is its static method.
            int[] highscore = new int[readFromFile.Length];     // we must have integer array equal length of data read from file.


            //data was read in String array. as you know score is in integer format. so you need to parse it.
            for (int i = 0; i < highscore.Length; i++) {
                highscore[i] = int.Parse(readFromFile[i]); 
            }
            highscore = sortInteger(highscore); // Sorting function is called to sort array in ascending order.
             // to show only top scorers you need to start loop in the reverse order. for top three scorers you bound it for 3 iterations.
            for (int i = (highscore.Length - 1); i > (highscore.Length - 4); i--) {
                MessageBox.Show(highscore[i].ToString());
            }
        }
        private int[] sortInteger(int[] highscore) {
            //Sorting array
            Array.Sort(highscore);
            return highscore;
        }
    }
}




/////////////////////////////////////////////// Menu Window Ends////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////// Game Play Starts//////////////////////////////////////////////////////////////////////////////////////////



Game Play


XAML Code:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Snake Bit Game" Height="422" Width="642" ResizeMode="NoResize" Icon="/WpfApplication2;component/image/Snakeicon.png">
    <Grid Height="383">
        <Rectangle Name="rectangle1" Stroke="Black" Margin="0,46,0,12" />
        <Canvas Name="paintCanvas"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MaxWidth="642" MaxHeight="422" Margin="0,46,0,12">
            
        </Canvas>
        <Label Content="Score :" Height="40" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" />
        <Label  Height="40" HorizontalAlignment="Left" Name="scorelbl" VerticalAlignment="Top" FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" Margin="69,0,0,0" />
        <Label Content="Level :" FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" Height="40" HorizontalAlignment="Left" Margin="521,0,0,0" Name="label2" VerticalAlignment="Top" />
        <Label  FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" Height="40" HorizontalAlignment="Left" Margin="589,0,0,0" Name="levellbl" VerticalAlignment="Top" />
        <Label Content="Speed :" FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" Height="40" HorizontalAlignment="Left" Margin="114,0,0,0" Name="speedlbl" VerticalAlignment="Top" />
        <Label Content="Snake Game v 1.0" FontFamily="Chiller" FontSize="24" FontWeight="SemiBold" Height="40" HorizontalAlignment="Left" Margin="268,0,0,0" Name="label3" VerticalAlignment="Top" >
            <Label.Effect>
                <DropShadowEffect />
            </Label.Effect>
        </Label>
    </Grid>
</Window>



C# Code: With Comments


using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
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.Shapes;

namespace WpfApplication1
{
    using System.Windows.Threading;

    public partial class Window1 : Window
    {


        // This list describes the Bonus Red pieces of Food on the Canvas
        private List<Point> bonusPoints = new List<Point>();

        // This list describes the body of the snake on the Canvas
        private List<Point> snakePoints = new List<Point>();

        /// <summary>
        /// Size of snake and eatables things
        /// </summary>
        
        private Brush snakeColor = Brushes.Green;
        private enum SIZE
        {
            THIN = 4,
            NORMAL = 6,
            THICK = 8
        };

        /// <summary>
        /// Moving Diection of snake can be changed from here.
        /// </summary>

        private enum MOVINGDIRECTION
        {
            UPWARDS = 8,
            DOWNWARDS = 2,
            TOLEFT = 4,
            TORIGHT = 6
        };

        /// <summary>
        /// Speed of Snake can be changed from here
        /// </summary>

        private TimeSpan FAST = new TimeSpan(10000);          // Fast Speed
        private TimeSpan MODERATE = new TimeSpan(30000);     // moderate speed of snake can be handled here.
        private TimeSpan SLOW = new TimeSpan(90000);        // SLow Speed
        
        

        private Point startingPoint = new Point(100, 100);
        private Point currentPosition = new Point();

        // Movement direction initialisation
        private int direction = 0;

        /* Placeholder for the previous movement direction
         * The snake needs this to avoid its own body.  */
        private int previousDirection = 0;

        /* Here user can change the size of the snake. and eatable things
         * Possible sizes are THIN, NORMAL and THICK */
        private int headSize = (int)SIZE.THICK; 



        private int length = 50;   // length of snake is handled here.
        private int score = 0;      // Initiatl score.
        private Random rnd = new Random();  // Random number which will add red balls for snake.
        private DispatcherTimer timer;


        public Window1()
        {
            InitializeComponent();
            timer = new DispatcherTimer();
            timer.Tick += new EventHandler(timer_Tick);



            levellbl.Content = "1"; // level Label Number Setting
            speedlbl.Content = "Speed : Slow";  // speed Setting here

            /* Here user can change the speed of the snake. 
             * Possible speeds are FAST, MODERATE, SLOW and DAMNSLOW */
            timer.Interval = SLOW; // Speed is Slow
            timer.Start();


            this.KeyDown += new KeyEventHandler(OnButtonKeyDown);   // On any key down on keyboard device it will be triggered.
            paintSnake(startingPoint);                              //Starting point of snake.
            currentPosition = startingPoint;
            // Instantiate Food Objects
            int num = 0;
            for (int n = 0; n < 1; n++)
            {
                paintBonus(num);
            }
        }

        
       
        private void paintSnake(Point currentposition)
        {

            /* This method is used to paint a frame of the snake´s body
             * each time it is called. */

                Ellipse newEllipse = new Ellipse();
                newEllipse.Fill = snakeColor;
                newEllipse.Width = headSize;
                newEllipse.Height = headSize;
                Canvas.SetTop(newEllipse, currentposition.Y);
                Canvas.SetLeft(newEllipse, currentposition.X);

                int count = paintCanvas.Children.Count;
                paintCanvas.Children.Add(newEllipse);
                snakePoints.Add(currentposition);


                // Restrict the tail of the snake
                if (count > length)
                {
                    paintCanvas.Children.RemoveAt(count - length);
                    snakePoints.RemoveAt(count - length);
                }
              
        }
        private void paintBonus(int index)
        {
            Point bonusPoint = new Point(rnd.Next(5, 620), rnd.Next(5, 315));     // New points are generated which will add red balls.

                //// Eatable red balls start////

                Ellipse newEllipse = new Ellipse();
                newEllipse.Fill = Brushes.Red;
                newEllipse.Width = headSize;
                newEllipse.Height = headSize;
                
                Canvas.SetTop(newEllipse, bonusPoint.Y);
                Canvas.SetLeft(newEllipse, bonusPoint.X);
                paintCanvas.Children.Insert(index, newEllipse);
                bonusPoints.Insert(index, bonusPoint);
            //// Eatable red balls End////
            
        }


        private void timer_Tick(object sender, EventArgs e)
        {
            // Expand the body of the snake to the direction of movement

                switch (direction)
                {
                    case (int)MOVINGDIRECTION.DOWNWARDS:
                        currentPosition.Y += 1;
                        paintSnake(currentPosition);
                        break;
                    case (int)MOVINGDIRECTION.UPWARDS:
                        currentPosition.Y -= 1;
                        paintSnake(currentPosition);
                        break;
                    case (int)MOVINGDIRECTION.TOLEFT:
                        currentPosition.X -= 1;
                        paintSnake(currentPosition);
                        break;
                    case (int)MOVINGDIRECTION.TORIGHT:
                        currentPosition.X += 1;
                        paintSnake(currentPosition);
                        break;
                }

                // Restrict to boundaries of the Canvas
                if ((currentPosition.X < 5) || (currentPosition.X > 620) ||
                    (currentPosition.Y < 5) || (currentPosition.Y > 315))
                    GameOver();

                // Hitting a bonus Point causes the lengthen-Snake Effect
                int n = 0;
                foreach (Point point in bonusPoints)
                {

                    if ((Math.Abs(point.X - currentPosition.X) < headSize) && 
                        (Math.Abs(point.Y - currentPosition.Y) < headSize))
                    {
                        length += 10;
                        score += 10;

                        scorelbl.Content = score.ToString();
                        if (score == 50) {
                          //  MessageBox.Show("Level 1 Clear");
                            timer.Interval = MODERATE;
                            levellbl.Content = "2";
                            speedlbl.Content = "Speed : Moderate";  // speed Setting here
                        }
                        if (score == 100)
                        {
                            //MessageBox.Show("Level 2 Clear");
                            timer.Interval = FAST;
                            levellbl.Content = "3";
                            speedlbl.Content = "Speed : Fast";  // speed Setting here
                        }
                        // In the case of food consumption, erase the food object
                        // from the list of bonuses as well as from the canvas
                        bonusPoints.RemoveAt(n);
                        paintCanvas.Children.RemoveAt(n);
                        paintBonus(n);
                        break;
                    }
                    n++;
                }

                // Restrict hits to body of Snake


                for (int q = 0; q < (snakePoints.Count - headSize*2); q++)
                {
                    Point point = new Point(snakePoints[q].X, snakePoints[q].Y);
                    if ((Math.Abs(point.X - currentPosition.X) < (headSize)) &&
                         (Math.Abs(point.Y - currentPosition.Y) < (headSize)) )
                    {
                        GameOver();
                        break;
                    }

                }
        }
        private void OnButtonKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Down:
                    if (previousDirection != (int)MOVINGDIRECTION.UPWARDS)
                        direction = (int)MOVINGDIRECTION.DOWNWARDS;
                    break;
                case Key.Up:
                    if (previousDirection != (int)MOVINGDIRECTION.DOWNWARDS)
                        direction = (int)MOVINGDIRECTION.UPWARDS;
                    break;
                case Key.Left:
                    if (previousDirection != (int)MOVINGDIRECTION.TORIGHT)
                        direction = (int)MOVINGDIRECTION.TOLEFT;
                    break;
                case Key.Right:
                    if (previousDirection != (int)MOVINGDIRECTION.TOLEFT)
                        direction = (int)MOVINGDIRECTION.TORIGHT;
                    break;

            }
            previousDirection = direction;
        }

        private void GameOver()
        {
            StreamWriter writeData = new StreamWriter("Highscore.txt", true);
            writeData.WriteLine(score);
            writeData.Close();
            MessageBox.Show("You Lose! Your score is "+ score.ToString(), "Game Over", MessageBoxButton.OK, MessageBoxImage.Hand);
            this.Close();
        }
    }
}






No comments:

Post a Comment