Corona Shooter Game in C-sharp – game tutorial.

Game tutorial: Corona shooter game in C-sharp (c#) : Je vindt hier het spel maar ook de broncode om het game zelf te programmeren. Gewoon door andere tekeningen te gebruiken kan je er een ander game van maken. Bijvoorbeeld een 2D space shooter.

🇬🇧 🇺🇸 This article in English : Shooter Corona Game Tutorial in C#

Corona shooter game in C# + source code.

Hier kan je het spel downloaden. Let op: Dit is geschreven in het Dot.NET framework van C# V4.x Als het niet werkt wil dit dus zeggen dat je dit framework nog niet hebt. Je kan dit GRATIS downloaden op Microsoft :

donet-framework-microsoft

Het voordeel van dit framework is, dat dit gemakkelijk overdraagbaar is naar andere systemen. Dus als je de framework op een apple-pc installeert, Dan werkt deze shooter dus ook op een Apple pc.

Corona Shooter Game in action

Hoe ziet deze game eruit? Wel daarvoor heb ik een kort youtube filmpje gemaakt. Maar nogmaals je kan er een volledig ander game van maken. Gewoon door andere tekeningen te gebruiken.

Dit is een vrij simpel spel. Goed om te leren programmeren in C#.

Shooter zelf programeren? Dat kan:

Ik gebruik hiervoor de visual Studio van Microsoft. Dit is geen uitleg over hoe je visual studio moet gebruiken. Dus dit is geen beginners tutorial. Maar voor de iets gevorderden.

Als je de werking volledig begrijpt. Kan je deze code natuurlijk tweaken om meer en complexere spelregels in te voeren. Bijvoorbeeld met een extra timer om zelf te schieten. (nu vuurt hij automatisch)

Hieronder staat de listing van de Corona shooter game code:

Dit is 1 lange listing (normaal 426 lijnen code). Maar ik heb die in stukken geknipt om tussendoor nog wat uitleg in te voegen. Alles komt dus op de code pagina van uw Form1.cs. Al de rest van de code wordt door Visual studio zelf gegenereerd op het moment dat je een nieuw project aanmaakt in de ontwikkel software.

Initialiseren en variabelen

using System;
using System.Drawing;
using System.Windows.Forms;
using WMPLib;
/*
 Copyright (c) Bruno Stroobandt - Infonosity.net
 V1.0 - 2020-03-09 YMD
     */

namespace SpaceGame
{
    public partial class Form1 : Form
    {
        WindowsMediaPlayer gameMedia;
        WindowsMediaPlayer shootMedia;
        WindowsMediaPlayer explosions;

        PictureBox[] stars;
        PictureBox[] munitions;
        PictureBox[] enemies;
        PictureBox[] enemiesMunition;

        private int backgroundspeed;
        private int playerSpeed;
        private int munitionsSpeed;
        private int enemiesSpeed;
        int enemiesMunitionSpeed;
        Random rnd;

        private int score;
        private int level;
        private int dificulty;
        private bool pause;
        private bool gameIsOver;
        

Game hoofdprogramma

Dit wordt uitgevoerd op het moment dat het form geladen wordt, en als je op de replay knop drukt.

        public Form1()
        {
            InitializeComponent();
            Load += Form1_Load; //laad het form
        }

        public void Form1_Load(object sender, EventArgs e)
        {
            backgroundspeed = 4;
            playerSpeed = 4;
            enemiesSpeed = 4;
            munitionsSpeed = 20;
            enemiesMunitionSpeed = 4;
            stars = new PictureBox[15];
            munitions = new PictureBox[3];
            rnd = new Random();

            //load immages
            Image munition = Image.FromFile(@"asserts\munition.png");

            Image enemie1 = Image.FromFile(@"asserts\E1.png");
            Image enemie2 = Image.FromFile(@"asserts\E2.png");
            Image enemie3 = Image.FromFile(@"asserts\E3.png");
            Image boss1 = Image.FromFile(@"asserts\Boss1.png");
            Image boss2 = Image.FromFile(@"asserts\Boss2.png");


            //init enemies PBox
            enemies = new PictureBox[10];

            for (int i = 0; i < enemies.Length; i++)
            {
                enemies[i] = new PictureBox();
                enemies[i].Size = new Size(40, 40);
                enemies[i].SizeMode = PictureBoxSizeMode.Zoom;
                enemies[i].BorderStyle = BorderStyle.None;
                enemies[i].Visible = false;
                Controls.Add(enemies[i]);
                enemies[i].Location = new Point((i + 1) * 50, -50);
            }
            enemies[0].Image = boss1;
            enemies[1].Image = enemie2;
            enemies[2].Image = enemie3;
            enemies[3].Image = enemie3;
            enemies[4].Image = enemie1;
            enemies[5].Image = enemie1;
            enemies[6].Image = enemie3;
            enemies[7].Image = enemie3;
            enemies[8].Image = enemie2;
            enemies[9].Image = boss2;

            //init bullets
            for (int i = 0; i < munitions.Length; i++)
            {
                munitions[i] = new PictureBox();
                munitions[i].Size = new Size(12, 12);
                munitions[i].Image = munition;
                munitions[i].SizeMode = PictureBoxSizeMode.Zoom;
                munitions[i].BorderStyle = BorderStyle.None;
                Controls.Add(munitions[i]);
            }
            //create Win Media Player
            gameMedia = new WindowsMediaPlayer();
            shootMedia = new WindowsMediaPlayer();
            explosions = new WindowsMediaPlayer();
            //load the sounds
            gameMedia.URL = "songs\\GameSong.mp3";
            shootMedia.URL = "songs\\shoot.mp3";
            explosions.URL = "songs\\boom.mp3";
            //setup songs playstyle
            gameMedia.settings.setMode("loop", true);
            gameMedia.settings.volume = 6;
            shootMedia.settings.volume = 2;
            explosions.settings.volume = 8;

            //init enemies munition
            enemiesMunition = new PictureBox[10];
            for (int i = 0; i < enemiesMunition.Length; i++)
            {
                enemiesMunition[i] = new PictureBox();
                enemiesMunition[i].Size = new Size(2, 25);
                enemiesMunition[i].BackColor = Color.Yellow;
                enemiesMunition[i].Visible = false;
                int x = rnd.Next(0, 10);
                enemiesMunition[i].Location = new Point(enemies[x].Location.X + 20, enemies[x].Location.Y - 20);
                Controls.Add(enemiesMunition[i]);

            }
           gameMedia.controls.play();

            score = 0;
            level = 1;
            dificulty = 9; // 9= easy - 1=hard
            pause = false;
            gameIsOver = false;


            
            for (int i = 0; i < stars.Length; i++)
            {
                stars[i] = new PictureBox
                {
                    BorderStyle = BorderStyle.FixedSingle,
                    Location = new Point(rnd.Next(20, 800), rnd.Next(-10, 400))
                };
                if (i % 2 == 1)
                {
                    stars[i].Size = new Size(2, 2);
                    stars[i].BackColor = Color.DarkGreen;
                }
                else
                {
                    stars[i].Size = new Size(3, 3);
                    stars[i].BackColor = Color.WhiteSmoke;
                }

                Controls.Add(stars[i]);
            }
            MoveBgTimer.Start();
        }

Game timer events:

Voor elke timer event, moet je een aparte timer op je form zetten. Het gemakkelijkste is dat je die timer daar aanmaakt, en er dan op dubbel-klikt. De procedure wordt dan aangemaakt in de listing. En daar typ je dan wat er moet gebeuren. (zo maak je zeker geen schrijffouten. Want 1 letter verkeerd, kan je een hoop grijze haren bezorgen 😎

 

        private void MoveBgTimer_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < stars.Length / 2; i++)
            {
                stars[i].Top = stars[i].Top + backgroundspeed;

                if (stars[i].Top >= this.Height)
                {
                    stars[i].Top = -stars[i].Height;
                }
            }

            for (int i = stars.Length / 2; i < stars.Length; i++)
            {
                stars[i].Top += backgroundspeed - 2;

                if (stars[i].Top >= this.Height)
                {
                    stars[i].Top = -stars[i].Height;
                }
            }

        }

        private void LeftMoveTimer_Tick(object sender, EventArgs e)
        {
            if (Player.Left > 10)
            {
                Player.Left -= playerSpeed;
            }
        }

        private void RightMoveTimer_Tick(object sender, EventArgs e)
        {
            if (Player.Left < 530)
            {
                Player.Left += playerSpeed;
            }
        }

        private void UpMoveTimer_Tick(object sender, EventArgs e)
        {
            if (Player.Top > 10)
            {
                Player.Top -= playerSpeed;
            }
        }

        private void DownMoveTimer_Tick(object sender, EventArgs e)
        {
            if (Player.Top < 395)
            {
                Player.Top += playerSpeed;
            }
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (!pause) 
            {
                if (e.KeyCode == Keys.Right)
                {
                    RightMoveTimer.Start();
                }
                if (e.KeyCode == Keys.Left)
                {
                    LeftMoveTimer.Start();
                }
                if (e.KeyCode == Keys.Down)
                {
                    DownMoveTimer.Start();
                }
                if (e.KeyCode == Keys.Up)
                {
                    UpMoveTimer.Start();
                }

            }
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            RightMoveTimer.Stop();
            LeftMoveTimer.Stop();
            UpMoveTimer.Stop();
            DownMoveTimer.Stop();
            if (e.KeyCode == Keys.Space) 
            {
                if (!gameIsOver) 
                {
                    if (pause)
                    {
                        StartTimers();
                        label1.Visible = false;
                        gameMedia.controls.play();
                        pause = false;
                    }
                    else 
                    {
                        label1.Location = new Point(this.Width / 2 - 120, 150);
                        label1.Text = "PAUSED";
                        label1.Visible = true;
                        gameMedia.controls.pause();
                        StopTimers();
                        pause = true;
                    }
                }
            }
        }

       

        private void MoveMunitionTimer_Tick(object sender, EventArgs e)
        {
            shootMedia.controls.play();
            for (int i=0; i < munitions.Length; i++) 
            {
            if (munitions[i].Top > 0) 
                {
                    munitions[i].Visible = true;
                    munitions[i].Top -= munitionsSpeed;
                    Collition();
                }
            else 
                {
                    munitions[i].Visible = false;
                    munitions[i].Location = new Point(Player.Location.X + 20 , Player.Location.Y -i *30);

                }
            }
        }

        private void MoveEnemieTimer_Tick(object sender, EventArgs e)
        {
            MoveEnemies(enemies,enemiesSpeed);
        }
        private void MoveEnemies(PictureBox[] array,int speed) 
        {
            for(int i = 0; i < array.Length; i++) 
            {
                array[i].Visible = true;
                array[i].Top += speed;
                if(array[i].Top > this.Height) 
                {
                    array[i].Location = new Point((i + 1) * 50, -200);
                }

            }
        }

En dan nog een paar subroutines voor onze shooter gaame.

Ook hier geld dat je de knoppen best tekent op de form en daar op dubbel klikt om zo de juiste subroutine aan te maken.

//andere subroutines:

        private void Collition() 
        {
        for (int i = 0; i < enemies.Length; i++)
            {
                if (munitions[0].Bounds.IntersectsWith(enemies[i].Bounds)
                    || munitions[1].Bounds.IntersectsWith(enemies[i].Bounds)
                    || munitions[2].Bounds.IntersectsWith(enemies[i].Bounds))
                {
                    explosions.controls.play();
                    score += 1;
                    scorelbl.Text = (score < 10) ? "0" + score.ToString() : score.ToString();
                    if (score % 30 == 0) 
                    {
                        level += 1;
                        levellbl.Text = (level < 10) ? "0" + level.ToString() : level.ToString();
                        if (enemiesSpeed <= 10 && enemiesMunitionSpeed <= 10 && dificulty >= 0) 
                        {
                            dificulty--;
                            enemiesSpeed++;
                            enemiesMunitionSpeed++;
                        }
                        if (level == 10) 
                        {
                            GameOver("WOW - Well Done !!!");
                        }
                    }

                    enemies[i].Location = new Point((i + 1) * 50, -100);
                }
                if (Player.Bounds.IntersectsWith(enemies[i].Bounds)) 
                {
                    explosions.settings.volume = 30;
                    explosions.controls.play();
                    Player.Visible = false;
                    GameOver("Game Over");
                }
            }
        
        }
        private void GameOver(string str)
        {
            label1.Text = str;
            label1.Location = new Point(120, 100);
            label1.Visible = true;
            ReplayBtn.Visible = true;
            ExitBtn.Visible = true;
            gameMedia.controls.stop();
            StopTimers();
        }
        //stop timers
        private void StopTimers ()
        {
            MoveBgTimer.Stop();
            MoveEnemieTimer.Stop();
            MoveMunitionTimer.Stop();
            EnemiesMunitionTimer.Stop();
        }
        private void StartTimers() 
        {
            MoveBgTimer.Start();
            MoveEnemieTimer.Start();
            MoveMunitionTimer.Start();
            EnemiesMunitionTimer.Start();

        }

        private void EnemiesMunitionTimer_Tick(object sender, EventArgs e)
        {
            for (int i = 0; i < (enemiesMunition.Length - dificulty); i++)
            {
                if (enemiesMunition[i].Top < this.Height)
                {
                    enemiesMunition[i].Visible = true;
                    enemiesMunition[i].Top += enemiesMunitionSpeed;
                    CollitionWithEnemiesMunition();
                }
                else
                {
                    enemiesMunition[i].Visible = false;
                    int x = rnd.Next(0, 10);
                    enemiesMunition[i].Location = new Point(enemies[x].Location.X + 20, enemies[x].Location.Y + 30);

                }
            }
        }
        private void CollitionWithEnemiesMunition() 
        {
            for (int i = 0; i < enemiesMunition.Length; i++) 
            {
                if (enemiesMunition[i].Bounds.IntersectsWith(Player.Bounds)) 
                {
                    enemiesMunition[i].Visible = false;
                    explosions.settings.volume = 30;
                    explosions.controls.play();
                    Player.Visible = false;
                    GameOver("Game Over");
                }
            }


        }

        private void ReplayBtn_Click(object sender, EventArgs e)
        {
            this.Controls.Clear();
            StopTimers();
            InitializeComponent();
            StartTimers();
            Load -= Form1_Load; //ontlaad het form

            Form1_Load(sender, e);
        }

        private void ExitBtn_Click(object sender, EventArgs e)
        {
            Environment.Exit(1);
        }
    }
}

De tekeningen van de corona shooter game:

Ja, de sterren zijn gewoon picture boxes. De virussen in deze game zijn tekeningen. Maar je moet wel iets creatief zijn, als je wil claimen dat je de game zelf hebt gemaakt. De tekeningen moet je dus zelf maken. Of download de gecompileerde versie bovenaan. In die zip zitten ook de tekeningen. Maar als je deze vervangt door ruimte schepen, dan heb je meteen een space-shooter game 🙂


Terug naar Computer – index

Lijkt dit wat moeilijk? Dan kan je ook eens kijken bij Just Basic Basketball Game. Dit is echt een programmeertaal voor beginners.