Click here to Skip to main content
Click here to Skip to main content

Sample Game Part I

By , 26 Jun 2007
 
Screenshot - Sample_Game

Introduction

This is a sample game to demonstrate reading keyboard strokes and moving a character.

Somehow, it's a space invaders-like game, except that there's nothing to shoot!!

You can also control the speed of the character and bullet.

Initializing the Game

The game starts by initializing the bullet and character's speed:

bullet_speed = 4;
character_speed = 2; 

Notice that I've used the same values in the numlists.

Moving the Character

In order to move the character, we start by reading the currently pressed key and determine which direction to move within the form boundaries (explained later).

The character is moved by creating a new point each time in the same direction of the key's value and adding the character_speed to that point.

private void MainCourse_KeyDown(object sender, KeyEventArgs e)
{
switch(e.KeyCode.ToString())
{
case "Up":
...
}
} 

Moving Within the Form

To restrict character movement within the form boundaries, I had to first calculate the allowed area. This was performed simply by subtracting one character dimension from one form's dimension and setting that number as a condition to move in the said direction:

case "Right":
if(Character.Location.X < (this.Size.Width - (Character.Width+10)))
Character.Location = new Point(Character.Location.X
+ character_speed, Character.Location.Y);
break;

case "Down":
if(Character.Location.Y < (this.Size.Height - (Character.Height+29)))
Character.Location = new Point(Character.Location.X,
Character.Location.Y + character_speed);
break;

Notice that only Right and Down directions have to be watched. Left and Up are of course already known (0,0).

Shoot!!

I know we have nothing to shoot!! However, please be nice enough to consider this part.

First, we need to initialize the bullet location (in this case, it's the character's location).

Bullet.Location = Character.Location; 

Now we set our bullet a location to appear, we can call her to stop being shy and come!!

Bullet.Visible = true; 

The next two lines are to have a base for the starting bullet position, otherwise, it won't quit following the character!!

bullet_x = Convert.ToInt32(Character.Location.X);
bullet_y = Convert.ToInt32(Character.Location.Y); 

Killing the Killer

Poor little bullet, I think it's the only thing that gets killed in this game!!

Once again, we have to determine the bullet's location in order to terminate it:

if(Bullet.Location.Y >= Bullet.Height)
{
Bullet.Location = new Point(bullet_x,bullet_y);
bullet_y -= bullet_speed;
}

else
kill_bullet(); 

The bullet is simply killed by stopping its timer and setting its visibility back again to false.

Shoot.Stop();
Bullet.Visible = false; 

I think it's about time we look at it all together.

The Code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using tonysound;

namespace MoveMe
{
    public partial class Game_sample : Form
    {
        int bullet_speed;
        int character_speed;
        int bullet_x;
        int bullet_y;

        public Game_sample()
        {
            InitializeComponent();
            bullet_speed = 4;
            character_speed = 2;
        }

        private void MainCourse_KeyDown(object sender, KeyEventArgs e)
        {
            switch(e.KeyCode.ToString())
            {
                case "Up":
                    if (Character.Location.Y > 1)
			Character.Location = new Point
			(Character.Location.X, Character.Location.Y -
			character_speed);
                    break;

                case "Left":
                    if (Character.Location.X > 1)
			Character.Location = new Point
			(Character.Location.X - character_speed,
			Character.Location.Y);
                    break;

                case "Right":
                    if (Character.Location.X < 
			(this.Size.Width - (Character.Width+10)))
			Character.Location = new Point
			(Character.Location.X + character_speed,
			Character.Location.Y);
                    break;

                case "Down":
                    if (Character.Location.Y < 
			(this.Size.Height - (Character.Height+29)))
		  Character.Location = new Point
			(Character.Location.X, Character.Location.Y +
			character_speed);
                    break;                 

                case "Space":
                    if (!Shoot.Enabled)
                    {
                        Bullet.Location = Character.Location;
                        Bullet.Visible = true;
                        //getting the current location of
		      bullet_x = Convert.ToInt32(Character.Location.X); 
                        //the character to start with
		      bullet_y = Convert.ToInt32(Character.Location.Y); 

                        Sound.Play(Environment.GetFolderPath
			(Environment.SpecialFolder.ProgramFiles)
			+ @"\Windows NT\Pinball\SOUND8.WAV",
			PlaySoundFlags.SND_ASYNC);
                        Shoot.Start();
                    }
                 break;

                case "Escape":
                    btnHide_Options.Text = "&Hide";
                    Options_panel.Location= new Point
			((this.Width - Options_panel.Width) - 15, 5);
                    Options_panel.Visible = true;
		  btnHide_Options.Focus();
                    break;

                default:
                    MessageBox.Show(@"
			Up: Move up
			Right: Move right
			Left: Move left
			Down: Move down
			Space Bar: Fire
			Esc: Game Options","Sample
			game",MessageBoxButtons.OK,
			MessageBoxIcon.Information);
                    break;
            }
        }

        private void kill_bullet()
        {
            Shoot.Stop();
            Bullet.Visible = false;
        }

        private void Shoot_Tick(object sender, EventArgs e)
        {
            if(Bullet.Location.Y >= Bullet.Height)
            {
                Bullet.Location = new Point(bullet_x, bullet_y);
                bullet_y -= bullet_speed;
            }
            else
                kill_bullet();
        }

        private void Close_Options_Click(object sender, EventArgs e)
        {
            bullet_speed = Convert.ToInt32(numBullSpeed.Value);
            character_speed = Convert.ToInt32(numCharSpeed.Value);
            Options_panel.Visible = false;
            this.Focus();
        }

        private void Game_sample_Load(object sender, EventArgs e)
        {
            string strSystem = "system32";
            //replace the music path in the following line to your background music
            Sound.Play(Environment.GetFolderPath
		(Environment.SpecialFolder.System).TrimEnd
		(strSystem.ToCharArray())
		+ @"\Help\Tours\WindowsMediaPlayer\Audio\Wav\wmpaud3.wav",
		PlaySoundFlags.SND_ASYNC);
        }

        private void chMute_CheckedChanged(object sender, EventArgs e)
        {
            if(chMute.Checked)
                Sound.Play(@"Nothing.wav", PlaySoundFlags.SND_ASYNC);
            else
                Sound.Play(Environment.GetFolderPath
		(Environment.SpecialFolder.System)
	       	+ @"\oobe\images\title.wma", PlaySoundFlags.SND_ASYNC);
        }

        private void lnkAbout_LinkClicked
		(object sender, LinkLabelLinkClickedEventArgs e)
        {
            MessageBox.Show("Sample Game\nBy Muammar Yacoob", 
		"The CodeProject", MessageBoxButtons.OK, 
		MessageBoxIcon.Information);
        }

        private void numCharSpeed_ValueChanged(object sender, EventArgs e)
        {
            Sound.Play(Environment.GetFolderPath
		(Environment.SpecialFolder.ProgramFiles) + 
		@"\Windows NT\Pinball\SOUND16.WAV", PlaySoundFlags.SND_ASYNC);
        }

        private void numBullSpeed_ValueChanged(object sender, EventArgs e)
        {
            Sound.Play(Environment.GetFolderPath
		(Environment.SpecialFolder.ProgramFiles) + 
		@"\Windows NT\Pinball\SOUND16.WAV", PlaySoundFlags.SND_ASYNC);
        }
    }
}

Limitations

I couldn't cope up with playing two sounds simultaneously, any similar experience will be highly appreciated.

Notes

In order to decrease the demo size, I've used 2 sound effects and 1 background music from Windows, so make sure they exist on your PC, otherwise replace them with valid ones.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Muammar©
Retired QSoft
Yemen Yemen
Member
Biography?! I'm not dead yet!
www.QSoftOnline.com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralswitchmemberPaulo Zemek11 Nov '09 - 0:54 
Only to point that comparing strings is very slow.
It is much better to use the switch over the enum directly.
 
So, instead of:
switch(e.KeyCode.ToString())
 
do switch(e.KeyCode)
 
and, in the case, instead of:
case "Up":
 
do
 
case Keys.Up:
 

This way, you will only be comparing ints internally. Much faster, as there will not be a new string created, there will not be hashcode comparison and after the entire string comparison.
 

Also, using the enum is less error prone, as if you type:
case "up" it will not work.
GeneralRe: switchmember Muammar©16 Nov '09 - 5:14 
Thanks Paulo, I'm writing my second article of this series soon and will make sure this's implemented.
 

GeneralWaiting for next part.memberSouthmountain26 Jun '07 - 6:32 
Thanks for good work.
GeneralRe: Waiting for next part.member Muammar©25 Dec '09 - 5:49 
Hey mate,
PartII is out and I thought you might wanna take a look:
The wrapping image game trick[^]
 
Cheers, and Merry Christmas!
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 26 Jun 2007
Article Copyright 2007 by Muammar©
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid