DEV Community

Cover image for Let's Make a Top-Down Shooter Game in C# and Windows Forms 🤖
christine
christine

Posted on

Let's Make a Top-Down Shooter Game in C# and Windows Forms 🤖

I have a programming exam tomorrow and for me, the best way to practice is to make games! It's fun, challenging, and quick enough to keep my brain fresh. So today I thought, why not try and make a top-down shooter game in (yet another) Windows Form App? (Check out my Flappy Bird tutorial!)

Our game will surround a retired hitman who has been hired to take out a bunch of evil robots (every game needs a backstory, okay?). We'll be using C#, and free assets from Kenney. I do need to thank MooICT for the guidance along the way. Without further diddle-daddling, let's sharpen our C# skills! 😁

Here is a low-budget demo of our game. 👀


Step One: Creating The Game Interface

Before we jump into the code itself, we need to create the game interface. Open up Visual Studio and follow the process to create a Windows Forms App with C# (be careful not to choose the vb.net option!).
Robot Shooter

Then, download the assets from my GitHub repository and extract it. Import these assets into your project (you can drag in a picture box and import there if you are unsure).

Robot Shooter

Once imported, we need to start adding our objects onto our interface. Don't worry too much about where you place these objects, you can always come back later to change it around.

You need to insert the following:

Five Labels:

  • Three default labels.
  • A textAmmolabel where we will display the amount of bullets we have.
  • A textKillslabel to show the amount of kills we have.

Two Picture Boxes:

  • One named playerController.
  • One named robotController.

One Timer:

  • Named gameStart.

One Progress Bar:

  • Named playerHealth.

Robot Shooter

For the gameStart timer, make sure you change the following properties and add a gameStartEvent event to it.
Robot Shooter

Then for the robot add the "robot" tag, and for the player add the "player" tag. We will need these tags later for game handling.
Robot Shooter
Robot Shooter

The, we need to add our input listeners (keyUp and keyDown) so that we can move the player around using our keyboard.
Robot Shooter

Finally, let's add a new class to our project labeled Ammo.cs - we will need this later on to make bullets and create bullet spreads for our shooting function.
Robot Shooter
Robot Shooter


Step Two: Forms.cs

Before we do anything, let's create three functions that we will complete later on: spawnAmmo, shootMain, and spawnRobots. Please note that I renamed my Form to RoboShooter. The gameStartEvent, keyDown, and keyUp functions are declared automatically by our form and timer components (remember, we added it in the first step).

//Forms.cs 
namespace RoboShooter
{
    public partial class RoboShooter : Form
    {
        public RoboShooter()
        {
            InitializeComponent();
        }  

  //moves player when keys are pressed down
        private void keyDown(object sender, KeyEventArgs e)
        {  
        }

        //stops player movement when keys arent pressed
        private void keyUp(object sender, KeyEventArgs e)
        {
        }

        //timer event on game start
        private void gameStartEvent(object sender, EventArgs e)
        {
        }

        //function needed to spawn more ammo during game
        private void spawnAmmo()
        {
        }

        //allows the player to shoot the robots in the direction it faces
        private void shootMain(string direction)
        {
        }

        //spawns robots
        private void spawnRobots() 
        {
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Once you've done that, lets declare our public variables. We will make them public because they will be called by multiple functions (put simply). Read more on access modifiers if needed.

namespace RoboShooter
{
    public partial class RoboShooter : Form
    {
        //public variables needed for our functions
        //controls player position on screen
        bool keyup;
        bool keydown;
        bool keyleft;
        bool keyright;
        string playerDirection = "right";

        //state of game at game start
        bool gameOver = false;

        //player stats at game start
        double health = 100;
        int movementSpeed = 10;
        int ammoLevel = 7;
        int robotSpeed = 3;
        int annihilations = 0;
        Random random = new Random();

        public RoboShooter()
        {
            InitializeComponent();
        }

        //moves player when keys are pressed down
        private void keyDown(object sender, KeyEventArgs e)
        {

        }

        //stops player movement when keys arent pressed
        private void keyUp(object sender, KeyEventArgs e)
        {

        }

        //timer event on game start
        private void gameStartEvent(object sender, EventArgs e)
        {

        }

        //function needed to spawn more ammo during game
        private void spawnAmmo()
        {
        }

        //allows the player to shoot the robots in the direction it faces
        private void shootMain(string direction)
        {
        }

        //spawns robots
        private void spawnRobots()
        {
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {

        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Now, in our keydown() function, let's add the necessary code to move the game character around when the player presses on their arrow keys. We will not add the space key's listener (which we will use to shoot the robots) here to prevent the player from spamming bullets! Remember, the assets ml, mu, md, and mr come from the assets we imported (the pictures to use for each player direction).

        //moves player when keys are pressed down
        private void keyDown(object sender, KeyEventArgs e)
        {
            //player won't be able to move if game is over
            if (gameOver)
            {
                return;
            }

            //moves player left with left arrow key and sets image as "man-left"
            if (e.KeyCode == Keys.Left)
            {
                keyleft = true;
                playerDirection = "left"; 
                playerController.Image = Properties.Resources.ml; 
            }

            //moves player right with right arrow key and sets image as "man-right"
            if (e.KeyCode == Keys.Right)
            {
                keyright = true;
                playerDirection = "right";
                playerController.Image = Properties.Resources.mr;
            }

            //moves player down with right down key and sets image as "man-down"
            if (e.KeyCode == Keys.Down)
            {
                keydown = true;
                playerDirection = "down";
                playerController.Image = Properties.Resources.md;
            }

            //moves player up with right up key and sets image as "man-up"
            if (e.KeyCode == Keys.Up)
            {
                keyup = true;
                playerDirection = "up";
                playerController.Image = Properties.Resources.mu;
            }
        }
Enter fullscreen mode Exit fullscreen mode

Then, in our keyUp()function, we will add the necessary code that will stop the game character from moving when the player releases their arrow and space bar keys. We will also add our space key's listener here to decrease our ammo and initiate our "shooting" function.

        //stops player movement when keys arent pressed
        private void keyUp(object sender, KeyEventArgs e)
        {
            //player won't be able to move if game is over
            if (gameOver)
            {
                return;
            }

            //disables keys when not pressed
            if (e.KeyCode == Keys.Left)
            {
                keyleft = false;
            }

            if (e.KeyCode == Keys.Right)
            {
                keyright = false;
            }

            if (e.KeyCode == Keys.Down)
            {
                keydown = false;
            }

            if (e.KeyCode == Keys.Up)
            {
                keyup = false;
            }

            //if the space bar is pressed down - it's here to prevent spamming of key
            if (e.KeyCode == Keys.Space && ammoLevel > 0) 

            {
                //reduce ammo and shoots in the direction the  player faces
                ammoLevel--;
                shootMain(playerDirection);  

                //spawn ammo boxes if ammo is low (defined later)
                if (ammoLevel < 3) 
                {
                    spawnAmmo(); 
                }
            }
        }
Enter fullscreen mode Exit fullscreen mode

Okay, now we can go ahead and add the necessary code in our gameStartEvent().

First, we need to alter our health bar (progress bar) according to the state of our player.

        private void gameStartEvent(object sender, EventArgs e)
        {
            //if the player has enough health left, the progressbar will be shown
            if (health > 1)
            {
                progressHealth.Value = Convert.ToInt32(health);
                progressHealth.ForeColor = Color.Orange;
            }
            //else the player will be killed and game over is called
            else
            {
                playerController.Image = Properties.Resources.death; 
                gameStart.Stop();
                gameOver = true;
            }

            //if health is less than zero make bar red as warning
            if (health < 20)
            {
                progressHealth.ForeColor = Color.Red;
            }
       }

Enter fullscreen mode Exit fullscreen mode

Then, below our code above, we need to add our code that will display our players stats when they've killed robots or if their ammo levels change.

        private void gameStartEvent(object sender, EventArgs e)
        {
            ...
            //displays our player stats value on the form
            textAmmo.Text = ammoLevel.ToString();
            textKills.Text = annihilations.ToString();
        }
Enter fullscreen mode Exit fullscreen mode

Then we need to alter our movement speed depending on where we are in the form (so that we can actually move around instead of just turning in one place).

        private void gameStartEvent(object sender, EventArgs e)
        {
            ...
            //affect speed of payer according to their direction
            if (keyleft && playerController.Left > 0)
            {
                playerController.Left -= movementSpeed;
            }

            if (keyright && playerController.Left + playerController.Width < 930)
            {
                playerController.Left += movementSpeed;
            }

            if (keyup && playerController.Top > 60)
            {
                playerController.Top -= movementSpeed;
            }

            if (keydown && playerController.Top + playerController.Height < 700)
            {
                playerController.Top += movementSpeed;
            }
        }
Enter fullscreen mode Exit fullscreen mode

Okay, now the long piece of code starts (ouch for you). We will need to create a foreach loop that will affect our player and robot controls.

First, we will need to loop through our game to see if our game controllers (player and robot) are colliding with anything. If the player collides with the robots, our health decreases and we die. If the robot collides with the bullets (defined later in Ammo.cs), they die, our kill streak increases, and the robots need to respawn. If our bullets hit the frame, they disappear. Lastly, if the player collides with the ammo crates (defined later), we increase our ammo. Read more on the Control class. Are you ready?

        private void gameStartEvent(object sender, EventArgs e)
        {
            ...
            foreach (Control x in this.Controls)
            {
                //if the player runs over the ammo picture, they will pick it up (and the picture will dissapear), and their ammo level will increase
                if (x is PictureBox && x.Tag == "ammo")
                {
                    if (((PictureBox)x).Bounds.IntersectsWith(playerController.Bounds))
                    {
                        this.Controls.Remove(((PictureBox)x)); // remove the ammo picture box
                        ((PictureBox)x).Dispose(); 
                        ammoLevel += 7; 
                    }
                }

                //if our players bullet hits the frame of the form, the bullet will "dissapear"
                if (x is PictureBox && x.Tag == "bullet")
                {
                    if (((PictureBox)x).Left < 1 || ((PictureBox)x).Left > 930 || ((PictureBox)x).Top < 10 || ((PictureBox)x).Top > 700)
                    {
                        this.Controls.Remove(((PictureBox)x)); 
                        ((PictureBox)x).Dispose(); 
                    }
                }

                //player-robot interaction
                if (x is PictureBox && x.Tag == "robot")
                {

                    //if the robot runs into the player, our health goes down and we get a red background to show injury
                    if (((PictureBox)x).Bounds.IntersectsWith(playerController.Bounds) && gameOver == false)
                    {
                        health -= 1;
                        playerController.BackColor = Color.Red;
                    }
                    else
                    {
                        playerController.BackColor = Color.Transparent;
                    }

                    //will allow the robots to move towards the player (just like the player keys above, it will change the robots direction and image)
                    if (((PictureBox)x).Left > playerController.Left)
                    {
                        ((PictureBox)x).Left -= robotSpeed;
                        ((PictureBox)x).Image = Properties.Resources.rl;
                    }

                    if (((PictureBox)x).Top > playerController.Top)
                    {
                        ((PictureBox)x).Top -= robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.ru;
                    }

                    if (((PictureBox)x).Left < playerController.Left)
                    {
                        ((PictureBox)x).Left += robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.rr; 
                    }

                    if (((PictureBox)x).Top < playerController.Top)
                    {
                        ((PictureBox)x).Top += robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.rd; 
                    }
                }


                //if our player hits the robot with our bullets, then the robots is killed and more are spawned
                foreach (Control j in this.Controls)
                {
                    if ((j is PictureBox && j.Tag == "bullet") && (x is PictureBox && x.Tag == "robot"))
                    {
                        if (x.Bounds.IntersectsWith(j.Bounds))
                        {
                            //up our kill streak 
                            annihilations++;
                            //removes the robot(x) and the ammo(j)
                            this.Controls.Remove(j);
                            j.Dispose(); 
                            this.Controls.Remove(x);
                            x.Dispose(); 
                            //spawns more robots
                            spawnRobots();
                        }
                    }
                }
            }
      }
Enter fullscreen mode Exit fullscreen mode

We are finally done with our gameStartEvent() function! 🥴

Now, we can move on to our spawnAmmo() function, which will spawn ammo crates when our bullets run low!

        //function needed to spawn more ammo during game
        private void spawnAmmo()
        {
            //creates new PictureBox for ammo that will spawn randomly across screen
            PictureBox ammo = new PictureBox(); 
            ammo.BringToFront();
            ammo.Image = Properties.Resources.ammo;
            ammo.SizeMode = PictureBoxSizeMode.AutoSize;
            ammo.BackColor = Color.Transparent;
            ammo.Left = random.Next(10, 890);
            ammo.Top = random.Next(50, 600); 
            ammo.Tag = "ammo";

            //adds the controls needed to pick it up and dispose of it above
            this.Controls.Add(ammo); 
            playerController.BringToFront();

        }
Enter fullscreen mode Exit fullscreen mode

Then, we need to do the same for our shootMain() function, which will allow us to shoot "bullets" at the robots. In other words, it spawns the bullets.

        //allows the player to shoot the robots in the direction it faces (by spawning bullets)
        private void shootMain(string direction)
        {
            bullet shoot = new bullet(); 
            shoot.direction = direction;
            shoot.bulletLeft = playerController.Left + (playerController.Width / 2);
            shoot.bulletTop = playerController.Top + (playerController.Height / 2); 
            shoot.spawnBullets(this); 
        }
Enter fullscreen mode Exit fullscreen mode

Finally, we need to spawn our robots when they run low. We do this in our spawnRobots() function.

 //spawns robots
        private void spawnRobots()
        {
            PictureBox robots = new PictureBox(); 
            robots.Tag = "robot"; 
            robots.Image = Properties.Resources.rl; 
            robots.Left = random.Next(0, 900); 
            robots.Top = random.Next(0, 800); 
            robots.SizeMode = PictureBoxSizeMode.AutoSize; 
            robots.BackColor = Color.Transparent;
            this.Controls.Add(robots);
            playerController.BringToFront();
            robots.BringToFront();
        }
Enter fullscreen mode Exit fullscreen mode

Okay, so we can't test yet because our bullets object is not defined. We'll do that next, but for now, your code should look like the code below.

Full Forms.cs

namespace RoboShooter
{
    public partial class RoboShooter : Form
    {
        //public variables needed for our custom functions
        //controls player position on screen
        bool keyup;
        bool keydown;
        bool keyleft;
        bool keyright;
        string playerDirection = "right";

        //state of game at game start
        bool gameOver = false;

        //player stats at game start
        double health = 100;
        int movementSpeed = 10;
        int ammoLevel = 7;
        int robotSpeed = 3;
        int annihilations = 0;
        Random random = new Random();

        public RoboShooter()
        {
            InitializeComponent();
        }

        //moves player when keys are pressed down
        private void keyDown(object sender, KeyEventArgs e)
        {
            //player won't be able to move if game is over
            if (gameOver)
            {
                return;
            }

            //moves player left with left arrow key and sets image as "man-left"
            if (e.KeyCode == Keys.Left)
            {
                keyleft = true;
                playerDirection = "left"; 
                playerController.Image = Properties.Resources.ml; 
            }

            //moves player right with right arrow key and sets image as "man-right"
            if (e.KeyCode == Keys.Right)
            {
                keyright = true;
                playerDirection = "right";
                playerController.Image = Properties.Resources.mr;
            }

            //moves player down with right down key and sets image as "man-down"
            if (e.KeyCode == Keys.Down)
            {
                keydown = true;
                playerDirection = "down";
                playerController.Image = Properties.Resources.md;
            }

            //moves player up with right up key and sets image as "man-up"
            if (e.KeyCode == Keys.Up)
            {
                keyup = true;
                playerDirection = "up";
                playerController.Image = Properties.Resources.mu;
            }
        }

        //stops player movement when keys arent pressed
        private void keyUp(object sender, KeyEventArgs e)
        {
            //player won't be able to move if game is over
            if (gameOver)
            {
                return;
            }

            //disables keys when not pressed
            if (e.KeyCode == Keys.Left)
            {
                keyleft = false;
            }

            if (e.KeyCode == Keys.Right)
            {
                keyright = false;
            }

            if (e.KeyCode == Keys.Down)
            {
                keydown = false;
            }

            if (e.KeyCode == Keys.Up)
            {
                keyup = false;
            }

            //if the space bar is pressed down - it's here to prevent spamming of key
            if (e.KeyCode == Keys.Space && ammoLevel > 0) 

            {
                //reduce ammo and shoot in direction player faces
                ammoLevel--;
                shootMain(playerDirection);  

                //spawn ammo if ammo is low
                if (ammoLevel < 3) 
                {
                    spawnAmmo(); 
                }
            }
        }

        //timer event on game start
        private void gameStartEvent(object sender, EventArgs e)
        {
            //if the player has enough health left, the progressbar will be shown
            if (health > 1)
            {
                progressHealth.Value = Convert.ToInt32(health);
                progressHealth.ForeColor = Color.Orange;
            }
            //else the player will be killed and game over is called
            else
            {
                playerController.Image = Properties.Resources.death; 
                gameStart.Stop();
                gameOver = true;
            }

            //displays our player stats value on the form
            textAmmo.Text = ammoLevel.ToString();
            textKills.Text = annihilations.ToString();

            //if health is less than zero make bar red as warning
            if (health < 20)
            {
                progressHealth.ForeColor = Color.Red;
            }

            //affect speed of payer according to their direction
            if (keyleft && playerController.Left > 0)
            {
                playerController.Left -= movementSpeed;
            }

            if (keyright && playerController.Left + playerController.Width < 930)
            {
                playerController.Left += movementSpeed;
            }

            if (keyup && playerController.Top > 60)
            {
                playerController.Top -= movementSpeed;
            }

            if (keydown && playerController.Top + playerController.Height < 700)
            {
                playerController.Top += movementSpeed;
            }


            foreach (Control x in this.Controls)
            {
                //if the player runs over the ammo picture, they will pick it up (and the picture will dissapear), and their ammo level will increase
                if (x is PictureBox && x.Tag == "ammo")
                {
                    if (((PictureBox)x).Bounds.IntersectsWith(playerController.Bounds))
                    {
                        this.Controls.Remove(((PictureBox)x)); // remove the ammo picture box
                        ((PictureBox)x).Dispose(); 
                        ammoLevel += 7; 
                    }
                }

                //if our players bullet hits the frame of the form, the bullet will "dissapear"
                if (x is PictureBox && x.Tag == "bullet")
                {
                    if (((PictureBox)x).Left < 1 || ((PictureBox)x).Left > 930 || ((PictureBox)x).Top < 10 || ((PictureBox)x).Top > 700)
                    {
                        this.Controls.Remove(((PictureBox)x)); 
                        ((PictureBox)x).Dispose(); 
                    }
                }

                //player-robot interaction
                if (x is PictureBox && x.Tag == "robot")
                {

                    //if the robot runs into the player, our health goes down and we get a red background to show injury
                    if (((PictureBox)x).Bounds.IntersectsWith(playerController.Bounds) && gameOver == false)
                    {
                        health -= 1;
                        playerController.BackColor = Color.Red;
                    }
                    else
                    {
                        playerController.BackColor = Color.Transparent;
                    }

                    //will allow the robots to move towards the player (just like the player keys above, it will change the robots direction and image)
                    if (((PictureBox)x).Left > playerController.Left)
                    {
                        ((PictureBox)x).Left -= robotSpeed;
                        ((PictureBox)x).Image = Properties.Resources.rl;
                    }

                    if (((PictureBox)x).Top > playerController.Top)
                    {
                        ((PictureBox)x).Top -= robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.ru;
                    }

                    if (((PictureBox)x).Left < playerController.Left)
                    {
                        ((PictureBox)x).Left += robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.rr; 
                    }

                    if (((PictureBox)x).Top < playerController.Top)
                    {
                        ((PictureBox)x).Top += robotSpeed; 
                        ((PictureBox)x).Image = Properties.Resources.rd; 
                    }

                }


                //if our player hits the robot with our bullets, then the robots is killed and more are spawned
                foreach (Control j in this.Controls)
                {
                    if ((j is PictureBox && j.Tag == "bullet") && (x is PictureBox && x.Tag == "robot"))
                    {
                        if (x.Bounds.IntersectsWith(j.Bounds))
                        {
                            //up our kill streak
                            annihilations++;
                            //removes the robot(x) and the ammo(j)
                            this.Controls.Remove(j);
                            j.Dispose(); 
                            this.Controls.Remove(x);
                            x.Dispose(); 
                            //spawns more robots
                            spawnRobots();
                        }
                    }
                }
            }
        }

        //function needed to spawn more ammo during game
        private void spawnAmmo()
        {
            //creates new PictureBox for ammo that will spawn randomly across screen
            PictureBox ammo = new PictureBox(); 
            ammo.BringToFront();
            ammo.Image = Properties.Resources.ammo;
            ammo.SizeMode = PictureBoxSizeMode.AutoSize;
            ammo.BackColor = Color.Transparent;
            ammo.Left = random.Next(10, 890);
            ammo.Top = random.Next(50, 600); 
            ammo.Tag = "ammo";

            //adds the controls needed to pick it up and dispose of it above
            this.Controls.Add(ammo); 
            playerController.BringToFront();

        }

        //allows the player to shoot the robots in the direction it faces (by spawning bullets)
        private void shootMain(string direction)
        {
            bullet shoot = new bullet(); 
            shoot.direction = direction;
            shoot.bulletLeft = playerController.Left + (playerController.Width / 2);
            shoot.bulletTop = playerController.Top + (playerController.Height / 2); 
            shoot.spawnBullets(this); 
        }

        //spawns robots
        private void spawnRobots()
        {
            PictureBox robots = new PictureBox(); 
            robots.Tag = "robot"; 
            robots.Image = Properties.Resources.rl; 
            robots.Left = random.Next(0, 900); 
            robots.Top = random.Next(0, 800); 
            robots.SizeMode = PictureBoxSizeMode.AutoSize; 
            robots.BackColor = Color.Transparent;
            this.Controls.Add(robots);
            playerController.BringToFront();
            robots.BringToFront();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step Three: Ammo.cs

Now head into your Ammo.cs file and define our base class: bullet.

//Ammo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

namespace RoboShooter
{
    //will spawn bullets on our screen
    class bullet
    {
    }
}

Enter fullscreen mode Exit fullscreen mode

Then, let's create our public variables as well as our two functions: spawnBullets() and bulletSpreadTick(). Remember to import the following libraries: Timer = System.Windows.Forms.Timer, System.Drawing, and System.Windows.Forms.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

namespace RoboShooter
{
    //will create bullets on our screen
    class bullet
    {
        //pulic variables
        public string direction;
        public int bulletSpeed = 20; 
        public int bulletLeft; 
        public int bulletTop;
        PictureBox Bullet = new PictureBox();
        Timer bulletSpread = new Timer();

        public void spawnBullets(Form form)
        {
        }

        //direction of the bullet
        public void bulletSpreadTick(object sender, EventArgs e)
        {
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In your spawnBullets() function, add the necessary code to create the bullets, as well as add the event handler to spread out the bullets (so it sprays like little cubes).

namespace RoboShooter
{
    //will create bullets on our screen
    class bullet
    {
        ...
        public void spawnBullets(Form form)
        {
            //creates the bullets, which will be little cubes when space bar is pressed 
            Bullet.BackColor = Color.Gold; 
            Bullet.Size = new Size(5, 5); 
            Bullet.Tag = "bullet"; 
            Bullet.Left = bulletLeft;
            Bullet.Top = bulletTop; 
            Bullet.BringToFront(); 

            //adds bullet to screen at x speed when button is pressed
            form.Controls.Add(Bullet); 
            bulletSpread.Interval = bulletSpeed; 
            bulletSpread.Tick += new EventHandler(bulletSpreadTick);
            bulletSpread.Start(); 
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Then, lastly, we can add the necessary code to our bulletSpreadTick() function so that we can move our bullets across the screen (spray) as well as make it disappear when it reaches a certain point.

namespace RoboShooter
{
    //will create bullets on our screen
    class bullet
    {
        //spread of the bullet
        public void bulletSpreadTick(object sender, EventArgs e)
        {
            if (direction == "left")
            {
                Bullet.Left -= bulletSpeed; 
            }

            if (direction == "right")
            {
                Bullet.Left += bulletSpeed;
            }

            if (direction == "up")
            {
                Bullet.Top -= bulletSpeed;
            }

            if (direction == "down")
            {
                Bullet.Top += bulletSpeed;
            }

            //if the bullets have reached a certain point from the player, it dissapears
            if (Bullet.Left < 16 || Bullet.Left > 860 || Bullet.Top < 10 || Bullet.Top > 616)
            {
                bulletSpread.Stop();
                bulletSpread.Dispose(); 
                Bullet.Dispose(); 
                bulletSpread = null; 
                Bullet = null; 
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And with that, all the coding is done.

Full Ammo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

namespace RoboShooter
{
    //will create bullets on our screen
    class bullet
    {
        //pulic variables
        public string direction;
        public int bulletSpeed = 20; 
        public int bulletLeft; 
        public int bulletTop;
        PictureBox Bullet = new PictureBox();
        Timer bulletSpread = new Timer();

        //will spawn the bullets
        public void spawnBullets(Form form)
        {
            //creates the bullets, which will be little cubes when space bar is pressed 
            Bullet.BackColor = Color.Gold; 
            Bullet.Size = new Size(5, 5); 
            Bullet.Tag = "bullet"; 
            Bullet.Left = bulletLeft;
            Bullet.Top = bulletTop; 
            Bullet.BringToFront(); 

            //adds bullet to screen at x speed when button is pressed
            form.Controls.Add(Bullet); 
            bulletSpread.Interval = bulletSpeed; 
            bulletSpread.Tick += new EventHandler(bulletSpreadTick);
            bulletSpread.Start(); 
        }

        //direction of the bullet
        public void bulletSpreadTick(object sender, EventArgs e)
        {
            if (direction == "left")
            {
                Bullet.Left -= bulletSpeed; 
            }

            if (direction == "right")
            {
                Bullet.Left += bulletSpeed;
            }

            if (direction == "up")
            { 
                Bullet.Top -= bulletSpeed;
            }

            if (direction == "down")
            {
                Bullet.Top += bulletSpeed;
            }

            //if the bullets have reached a certain point from the player, it dissapears
            if (Bullet.Left < 16 || Bullet.Left > 860 || Bullet.Top < 10 || Bullet.Top > 616) 
            {
                bulletSpread.Stop();
                bulletSpread.Dispose(); 
                Bullet.Dispose(); 
                bulletSpread = null; 
                Bullet = null; 
            }
        } 
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

To wrap things up, you can now make it your own by adding more features, and making the interface of the game a lot more interesting. You can find cool assets from Kenney's site above, or even Freepik. I did something basic. 🤔
Robot Shooter
Robot Shooter
Robot Shooter

I hope this was easy enough to follow. I'm no C# master, but for me this was good enough to practice a bit. I do want to improve on this game, maybe smoothen out the movement and add sound, but hey, that's for future me to worry about! Until next time, happy coding. 😁

The full source code can be found on my GitHub.

Top comments (1)

Collapse
 
andrewbaisden profile image
Andrew Baisden

Damn thats dope! One day I want to do stuff like this thats why I learned C#.