C# Tutorial – Create a simple Color Switch game in Visual Studio

In this tutorial we will be creating a simple and fun clone of the popular color switch game. We put our own spin into the game concept itself because it makes for better learning opportunity. In the original game you play as a blob jumping across different colored objects in this game you are a colored square where the other blocks are coming towards you. To win points you will have to change your block color to match the incoming ones. As a bonus we also added a game speed up function too so its make it more challenging as you progress in the game.

Lesson objectives –

  1. Create a fun color switch game in visual studio with C#
  2. Use Key events and timer events in windows form application
  3. Use LIST, INT, RANDOM and BOOLEAN data types in the game
  4. Add a record keeper in the game, A list item which keeps the last played score
  5. Randomly spawn the blocks and place them dynamically in the game
  6. Linking Key Press events to the Form
  7. Creating a custom game reset function

Full Video Tutorial

Download Color Switch Project on GitHub

 

To start this tutorial, lets load up Visual Studio and start new project

Lets call this project colorSwitch and press OK.

This is the form view so far. We need to make some changes to the form in the properties window. So lets go do that now.

Change the following in the properties window

Size – 774, 595

Text – Color Switch MOOICT

The form should look like this now

With that done we now need to add some of the elements for the game.

From the toolbox add the following

A panel

Drag and drop it to the Form.

While the panel is selected change the following in its properties window.

Back Color – Black

Location – 0, 0

Size – 481, 550

What does a panel do – A panel is good for grouping multiple objects together. In this case we will use this panel to group our picture boxes together. The player will play this game inside of this panel. So technically this black screen is the general game area for this game.

Now lets add the 3 picture boxes inside this panel.

Drag and drop 3 picture boxes in it, now remember since the background of the panel is black, the picture boxes inserted in it will inherit the background color don’t worry about that because we will change them once all of them are in it.

Drag and drop 3 of them in the panel

Lets start with the top picture box first. Select the top one and change the following to its properties.

Name – block2

Back Color – Red

Size – 518, 30

Location – -12, 36

Result –

Now click on the second picture box now and change the following to its properties

Name – block1

Back Color – Red

Size – 589, 25

Location – -12, 240

Result –

Now lets click on the final picture box and make the following changes to its properties.

Name – player

Back color – Yellow

Size – 90, 40

Location – 191, 502

Final result

Now lets add 2 labels to the form.

Add label 1 on the top and label 2 on the bottom. Click on the label 1 and let’s change the following in the properties.

Font – Size 16 BOLD.

Text – Score: 0.

Now click on the second label. Tip – you can add multi line to a single label. Visual studio allows us to write multiple lines in a single label. Lets see how.

While you have the label 2 selected go to the properties window, next to the text you will see the drop-down option. Now click on it and then this little white space will appear which means we able to create new paragraphs on a single label. Enter the text as you see it and change the font option to BOLD.

This is what the final version looks like.

Now lets add a list box to the form.

Drag and drop it to the form.

Select the list box and make the following changes to its properties window.

Name – scoreList

Enabled – False

Font – Size 11, Bold

Location – 493, 80

Size – 251, 378

Final result

The ideal plan is to place the score list box between the two labels. This box will be used to keep a record of each game play and what time it was played.

Now add a timer to form. Drag and drop a timer object on the form.

In the properties section of the timer, change the following name to gameTimer, Enabled to True and Interval to 20. We want this timer to run every 20 milliseconds.

Time to add some events –

First click on the timer

In the properties window, click on small lighting bolt icon. This icon will take you to the events manager window. Here we can add events that will be triggered by the object. Inside the tick option type playGame and press Enter.

Once you pressed enter, it will take you to the code view, for now come back to the design view as we have on more event to add.

Select the form. Do not select any other object on the form, if you are having trouble then simply click on the title bar of the form and it will select it.

In the event managers window find the key press event

Type in keyisDown and press enter.

This is the code view so far in this game –

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace colorSwitch
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void playGame(object sender, EventArgs e)
        {

        }

        private void KeyisDown(object sender, KeyPressEventArgs e)
        {

        }
    }
}

We have the key is down event and the play game event. Excellent. Now let’s add a custom function to reset the game.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace colorSwitch
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void playGame(object sender, EventArgs e)
        {

        }

        private void KeyisDown(object sender, KeyPressEventArgs e)
        {

        }

        public void resetGame()
        {

        }
    }
}

Let’s add some variables to the code. All the codes are commented so you will know what each line is doing. This function will be called when we want to reset the game to its default settings. For now, leave it blank.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace colorSwitch
{
    public partial class Form1 : Form
    {
        List<Color> colors; // create a list of colors for the game

        Random rnd = new Random(); // new instance of the random class called rnd

        Random blockPosition = new Random(); // new instance of the random class called block position

        int blockColor = 0; // integer that will determine the block colors

        int i; // integer that will change the players color

        int speed = 5; // speed of the blocks in the beginning of the game

        int score = 0; // default score of the game

        bool gameOver = false; // the default game over Boolean

        public Form1()
        {
            InitializeComponent();
        }

        private void playGame(object sender, EventArgs e)
        {

        }

        private void KeyisDown(object sender, KeyPressEventArgs e)
        {

        }

        public void resetGame()
        {

        }
    }
}

Random rnd = new Random() and Random blockPosition = new Random are both an instance of the random number genaretor class. The rnd random number will be used deterimine which color the blocks should have when they are scrolling down and the second blockposition will determine where these blocks respawn when they reach the bottom of the form.List<Color> colors; This is a list array which will hold the colors we want the player to switch between. Right now this array is empty and we will add the colors to in the reset function. Follow along.

Int backColor is the integer we will link with the rnd random number to change the blocks color.

Int speed is an interger that will allow use to speed up or down the scrolling blocks.

Int I will be used to change the players block color.

Int score is an integer that will keep the overall score for the game.

Bool gameover is a boolean which will determine if the game is over or not. This value can only change between true and false.

 

        public Form1()
        {
            InitializeComponent();
            resetGame(); // invoke the reset game function
        }

In the highlighted code above we are calling the reset function. The public form1() is the first function which runs first when the program is running. This is why we will run the resetGame() function with this. This will be able to load all of the default settings for the game.

        public void resetGame()
        {
            // this is the reset game function
            block1.Top = -80; // set the block 1 to top of the screen at -80 pixels
            block2.Top = -300; // set the block 2 to top of the screen at -300 pixels
            //below is the list of colors we will add for the player and the blocks

            colors = new List<Color> { System.Drawing.Color.Red, System.Drawing.Color.Yellow, System.Drawing.Color.White, System.Drawing.Color.Purple };

            i = 0; // i is set to 0 as default
            gameTimer.Start(); // start the game timer
            speed = 5; // set the default speed to 5 for the blocks
            score = 0; // default score is 0
        }

Above is the resetGame function. First we are resetting block1 and block2’s top property. This property allows us to scroll the blocks downward.In the highlighted code above we are calling the reset function. The public form1() is the first function which runs first when the program is running. This is why we will run the resetGame() function with this. This will be able to load all of the default settings for the game.

Then we have the colors array. In this function we are adding all of the colors into it. We start with colors = new List<Color> and then we use the curly brackets {} inside the curly brackets we adding the colors we want for this game. { System.Drawing.Color.Red, System.Drawing.Color.Yellow, System.Drawing.Color.White, System.Drawing.Color.Purple}. Now you might be thinking why are we using this System.Drawing.Color.Red or such that’s because in C# colors are a standard class we have to navigate inside the drawings class and then access the colors from there.

After the color we starting the game timer and setting the integer I, speed and score back to their default values.

        private void KeyisDown(object sender, KeyPressEventArgs e)
        {
            // if the player presses the space key we do the following
            if (e.KeyChar == (char)Keys.Space)
            {
                i++; // increase the i integer by 1

                // if the i integer is greater than the total colours we have in the list
                if (i > colors.Count - 1)
                {
                    // reset i back to 0
                    i = 0;
                }

                player.BackColor = colors[i]; // apply the color to players background
            }

            // if the key capital R or lower case r is pressed then we do the following
            // if the game is also true only then the game will reset else it will not do anything
            if (e.KeyChar == (char)Keys.R || e.KeyChar == char.ToLower((char)Keys.R) && gameOver)
            {
                // invoke the reset game function
                resetGame();
                gameOver = false; // now the game is reset we will set game over to false
            }
        }

In the first if statement we are checking if the SPACE key has been pressedAbove is the key is down function. In this function we will program in the SPACE key and R key accordingly.

Then we are increasing i by 1 hence the i++.

Then we have another if statement inside it which checking if I’s value is greater then the number of colors we have saved inside the colors list array the we are resetting i back to 0. So it doesn’t give us an error when it goes over instead it goes back to 0 and as we press space key it will increase the i again.

Outside that if statement you can see the we are adding the player.BackColor = colors[i] line. This line is letting us change the color of the player. Since the player object is a picture box without a picture we can change its background and use it as an object. If the I’s value 0 then the back color for player object will be RED if its 1 it will be yellow 2 is WHITE 3 is PURPLE and when it hits 4 it will reset back to RED.

In the second if statement we are checking if the player is pressing the R key. In this one there is a small problem we cannot allow the player to simply press the R key randomly only when the game is over. So in the if statement we are checking the following

IF CAP R is pressed OR LOW r is pressed AND game over is true

Then we run the reset game function and set game over to false.

Below is the play game function which will control all of the animation and logic of the game. All the codes have been commented through so make sure you check each line as you continue on.

        private void playGame(object sender, EventArgs e)
        {
            block1.Top += speed; // bring the block 1 towards the bottom of this form
            block2.Top += speed; // bring the block 2 towards the bottom of this form
            label1.Text = "Score " + score; // update the label to show how much score we have



            // if block 1 has reached bottom of the form then
            if (block1.Top > 500)
            {

                blockColor = rnd.Next(colors.Count); // choose a random color from the list
                block1.BackColor = colors[blockColor]; // apply the random color to block 1
                block1.Top = blockPosition.Next(200, 300) * -1; // randomly position the block on top of the form
                score++; // add 1 to the score

            }


            // if block 2 has reached bottom of the form
            if (block2.Top > 500)
            {
                // add block 1 is already on its way to the form and passed 200 pixels
                if (block1.Top > 100)
                {
                    blockColor = rnd.Next(colors.Count); // choose a random color from the list
                    block2.BackColor = colors[blockColor]; // apply the color to block 2
                    block2.Top = (block1.Top * 8) * -1; // randomly position the block on top of the form
                    score++; //add 1 to the score
                }
            }

            // if the player collides with block 1
            if (player.Bounds.IntersectsWith(block1.Bounds))
            {
                // if the player and block 1 DON'T have the same background color
                if (player.BackColor != block1.BackColor)
                {
                    // we will add the current score to the list box with the time which they were played
                  scoreList.Items.Add("Scored: " + score + " @"+ string.Format(" {0:HH:mm:ss tt}", DateTime.Now));
                    // game over
                  gameTimer.Stop(); // stop the timer

                    gameOver = true; // set game over to true now that the player has lost
                }
            }

            // if the player collides with block 2
            if (player.Bounds.IntersectsWith(block2.Bounds))
            {
                // if the player and block 2 DON'T have the same background color
                if (player.BackColor != block2.BackColor)
                {
                    // we will add the current score to the list box with the time which they were played
                 scoreList.Items.Add("Scored: " + score + " @" + string.Format(" {0:HH:mm:ss tt}", DateTime.Now));
                    // game over
                 gameTimer.Stop(); // stop the timer

                    gameOver = true; // set game over to true now that the player has lost
                }
            }

            // if the score is greater than 5 then we increase the speed to 6
            if (score > 5)
            {
                speed = 6;
            }
            // if the score is greater then 10 then we increase the speed to 8
            if (score > 10)
            {
                speed = 8;
            }


            block1.Refresh(); // refresh the block one so its not glitchy when scrolling down
            block2.Refresh(); // refresh the block two so its not glitchy when scrolling down
        }

block2.Top += speed; // bring the block 2 towards the bottom of this formblock1.Top += speed; // bring the block 1 towards the bottom of this form

label1.Text = “Score ” + score; // update the label to show how much score we have

In the timer we are assigning the speed integer to the block 1 and block 2 TOP property. This means it will scroll down at 5 pixels per second because speed integer has 5 inside it. Label1’s texts are getting linked to the score integer.

// if block 1 has reached bottom of the form then

if (block1.Top > 500)

{

blockColor = rnd.Next(colors.Count); // choose a random color from the list

block1.BackColor = colors[blockColor]; // apply the random color to block 1

block1.Top = blockPosition.Next(200, 300) * -1; // randomly position the block on top of the form

score++; // add 1 to the score

}

Since the blocks are going to scroll to the bottom of the screen we need to calculate when it reached it. Meaning the player successfully change its color thus the block made it through. In that case we will check if block 1’s top value reached more than 500 pixels from the top it will do the following

Generate a random number and store it inside the backColor Integer

Change the block 1’s back color to the that number we generated in the backColor integer

Move the block 1’s top position to a random number generated in the blockPosition random class and then multiply by -1 which means it will come up with a negative number. We need the block to be placed out of view from the top this is why we are putting a negative there the form starts from 0 pixels which is right at the top so if we place this block at -100 means it will be simply animate down from that position.

Lastly we are adding 1 to the score variable by using score++;

// if block 2 has reached bottom of the form

if (block2.Top > 500)

{

// add block 1 is already on its way to the form and passed 200 pixels

if (block1.Top > 100)

{

blockColor = rnd.Next(colors.Count); // choose a random color from the list

block2.BackColor = colors[blockColor]; // apply the color to block 2

block2.Top = (block1.Top * 8) * -1; // randomly position the block on top of the form

score++; //add 1 to the score

}

}

This is for block 2. Notice there after the block2.Top > 500 we have another if statement that’s checking the block 1’s position. Since we have two blocks in this game and both positions are being generated by a random number generator which means its mostly likely going to create numbers that are closer to each other. That means the player will not have enough time to change the blocks color and gain any points. To avoid this from happening we are checking if block 2 reached 500 pixels and block 1 is at 100 pixels then we can do whats inside the if statement otherwise it will simply wait.

// if the player collides with block 1

if (player.Bounds.IntersectsWith(block1.Bounds))

{

// if the player and block 1 DON’T have the same background color

if (player.BackColor != block1.BackColor)

{

// we will add the current score to the list box with the time which they were played

scoreList.Items.Add(“Scored: ” + score + ” @”+ string.Format(” {0:HH:mm:ss tt}”, DateTime.Now));

// game over

gameTimer.Stop(); // stop the timer

gameOver = true; // set game over to true now that the player has lost

}

}

In this if statement above we are checking if the player intersects or collides with block 1. In this case we also need to check if their background colors match. So we are checking if(player.BackColor != block1.BackColor) meaning if players back color and block 1’s back color is NOT equal then we will do this following

Add the information to the score list box show the score and time played

Stop the game timer

Change game over to true

If the colors are the same then this will not run.

// if the player collides with block 2

if (player.Bounds.IntersectsWith(block2.Bounds))

{

// if the player and block 2 DON’T have the same background color

if (player.BackColor != block2.BackColor)

{

// we will add the current score to the list box with the time which they were played

scoreList.Items.Add(“Scored: ” + score + ” @” + string.Format(” {0:HH:mm:ss tt}”, DateTime.Now));

// game over

gameTimer.Stop(); // stop the timer

gameOver = true; // set game over to true now that the player has lost

}

}

This is the collision detection with the block 2 object. Once again, we are doing the same thing. To be more efficient we could have done this in one large if statement but for learning purposes it made sense to do it separately.

// if the score is greater than 5 then we increase the speed to 6

if (score > 5)

{

speed = 6;

}

// if the score is greater than 10 then we increase the speed to 8

if (score > 10)

{

speed = 8;

}

Above we have two if statements now first one we are checking if score if greater than 5 then we can increase the speed to 6 and second, we are checking if score is greater than 10 then we can increase the speed to 10.

block1.Refresh(); // refresh the block one so its not glitchy when scrolling down

block2.Refresh(); // refresh the block two so its not glitchy when scrolling down

These two lines are above Re-Drawing the blocks on the screen to make it look more smooth. This is an optional line you can have it or not it will still work but it looks better with it.

Now lets debug the game Click on the start button or go through the debug drop down from the tool bar and click on start debugging.

The game is working, its keeping score and showing when I played last and with what score. Awesome. If you managed to follow this far then well done. If you are experiencing any errors in the code, check back with the tutorial and make sure you haven’t missed anything. Moo Out.




Comments are closed.