Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Fighter Space Ship Game

0.00/5 (No votes)
23 Oct 2012 2  
As the name suggests, you will be driving a space ship in galaxy and protecting yourself from meteors. Now to show ultrabook capability with the game I will be using touch and accelerometer.

This article is an entry in our AppInnovation Contest. Articles in this sub-section are not required to be full articles so care should be taken when voting.

Introduction

I was feeling boar and wanted to do something innovative. I love playing games and always wondered

  • How game will be developed?
  • How characters moves etc?

For this weekend I gave a shot to XNA Framework and For the App Innovation Contest, I propose creating a Fighter Space Ship game. It’s my first attempt to game programming,

As the name suggests, you will be driving a space ship in galaxy and protecting yourself from meteors. With this game, we also wanted to demostrate ultrabook capabilities.

Our game will demonstrate two main feature of ultrabook -

Touch Aware - The game will be touch aware, there will be two buttons, one which will speed up your space ship and another will put brake on space ship. This will give you greate control while driving space ship.

Accelerometer - The game will have accelerometer support. Player can just lift their ultrabook and feel the driving.

That way, the game need not to change when it ports on other devices like, windows phone, tablets etc.

Background

In order to understand this, you should have basic knowledge of C# programming. Your concepts with OOPs should be clear. As in game each and everything will be demonstrated to you as object.

Let's Begin

We will be developing a 2D game here.

I have started learning XNA by creating some 2D games. For 2D games first you got to learn about game templete, how things execute, game life cycle, how to show images on screen, how to move things, collision detection etc. Once you grab these basics then creating 2D games is just your creativity.

I will start right from scratch so even if you are developing your first game this tutorial will help you.

1) Prerequisites

In order to start developing XNA game. First you should have XNA Game Studio installed on your machine. XNA Game Studio have different vesions and currently running version is 4.0. Even if you install visual studio 2008 you will get XNA game studio 3.0 installed on your machine by default and with visual studio 2010 you will get game studio 4.0 installed.

If you dont have XNA game studio installed on your machine just make a google search, download it and intstall on your machine.

Obviously we need Visual Studio.

2) Understanding Game Template

2.1) Open XNA Project

I will be quickly explaining this section else this article will become too lengthy.

Open Visual Studio -> Select new project -> Select XNA Game Studio-> Select Windows Game.

Name it as FirstGame. Here we have different kind of templates for windows phone games, Xbox and windows game etc

XNA is very easy framework for developing games, it will hide all internal details and complexity and we just need to imagine and develop game. Here we don't just drag drop things, all you got to do is by coding only.

2.2) Understand Basics

This will open the Game Project for us. Notice you will have two sub project, FirstGame and FirstGameContent

FirstGame project will contain all your game logic and FirstGameContent project will contains all your game contents. Game content can be your images, audios, fonts and animations etc.

Your FirstGame project will contains program.cs which is starting point for your game and game1.cs file in your project, which is almost like you game only. This is starting point of game which will invoke other objects on screen. Let's look at its methods.

before proceding further lets just think of a game, how it should be, how it should execute in an endless manner. Let's look at below pseudocode.

Game1() – General initialization (Game1.cs)
Initialize() – Game initialization (Game1.cs)
LoadContent() – Load Graphics resources (Game1.cs)
Run() - Start game loop (Program.cs). In every step:
Update() - Read user input, do calculations, and test for game ending (Game1.cs)
Draw() – Renderization code (Game1.cs)
UnloadContent() – Free graphics resources (Game1.cs)

As the aboe pseudocode explains us everything. From program.cs we will create game1 object and invoke it.

The Draw method of game1 will call initialize only one time, then it will load content and start drawing objects on screen. In one second, on Xbox or Windows the update method will be called 60 times, so this is the place where we will read inputs, update game objects etc. Finally based on user input we will stop game and then its unload content method will be called.

Now look at below snippets, which is exactly same.

/// <summary>
    /// This is the main type for your game
        public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

       /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
        }

        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// <param name="gameTime" />Provides a snapshot of timing values.
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// This is called when the game should draw itself.
        /// <param name="gameTime" />Provides a snapshot of timing values.
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }

as its structure automatically explaining every thing. Till here you should have basic understanding of game, how it works etc. So we will start building game now and simultaneously I will keep explaining objects creating, moving and other animation concepts.

Start Game Development

Before stating developing Fighter Space Ship game, we need to plan for game, what all features will be there, how game will proceed, game state management.

What this game will do, you will be having a space ship which will be controlled by user input. There be meteors in galaxy will be moving and trying to block you. We need to escape from them and reach to our destination.

From above statement, we can thing of certain items as compnents of game.

  1. Your space ship will be an object which will be controlled by user.
  2. Meteor will be an object.
  3. Your game1.cs, main object will be controlling everything. Galaxy need not be an object, as we can draw an galaxy image in game1.cs only.

Below code for space ship will be used as an component

class SpaceShip : DrawableGameComponent
    {
        Texture2D shipTexture;
        Vector2 shipPosition;
        const int ShipHeight = 84;
        const int ShipWidth = 84;
        public SpaceShip(Game game)
            : base(game)
        {
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            shipTexture = Game.Content.Load<texture2d>("FighterSpaceShip");
            shipPosition = new Vector2(Artifacts.GamePreferedBufferWidth / 2 - ShipWidth/2, Artifacts.GamePreferedBufferHeight - ShipHeight);
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        public override void Update(GameTime gameTime)
        {
            //keyboard demo
            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Up))
                shipPosition += new Vector2(0, -3);
            if (keyboardState.IsKeyDown(Keys.Down))
                shipPosition += new Vector2(0, 3);
            if (keyboardState.IsKeyDown(Keys.Left))
                shipPosition += new Vector2(-3, 0);
            if (keyboardState.IsKeyDown(Keys.Right))
                shipPosition += new Vector2(3, 0);

            //keep space ship in bounds
            if (!GraphicsDevice.Viewport.Bounds.Contains(GetBounds()))
            {
                Rectangle screenBounds = GraphicsDevice.Viewport.Bounds;
                if (shipPosition.X < screenBounds.Left)
                {
                    shipPosition.X = screenBounds.Left;
                }
                if (shipPosition.X > screenBounds.Width - ShipWidth)
                {
                    shipPosition.X = screenBounds.Width - ShipWidth;
                }
                if (shipPosition.Y < screenBounds.Top)
                {
                    shipPosition.Y = screenBounds.Top;
                }
                if (shipPosition.Y > screenBounds.Height - ShipHeight)
                {
                    shipPosition.Y = screenBounds.Height - ShipHeight;
                }
            }
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            spriteBatch.Begin();
            spriteBatch.Draw(shipTexture, shipPosition, Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        public Rectangle GetBounds()
        {
            return new Rectangle((int)shipPosition.X, (int)shipPosition.Y,
                ShipWidth, ShipHeight);
        }

        public void RestSpaceShip()
        {
            shipPosition = new Vector2(Artifacts.GamePreferedBufferWidth / 2 - ShipWidth / 2, Artifacts.GamePreferedBufferHeight - ShipHeight);
        }
    }

as you can see the update and draw method of class, update is accepting user input from keyboard which will help spcae ship to move. Also notice that update method is not letting the spce ship go out of screen. Draw method is drawing space ship on screen.

Same way we can create meteor component. Please find below code for that.

public class Meteor : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Vector2 meteorPosition = Vector2.Zero;
        Vector2 meteorVelocity = Vector2.Zero;
        Texture2D meterorTexture;
        Random random;
        const int MeterorHeight = 56;
        const int MeterorWidth = 64;
        public Meteor(Game game)
            : base(game)
        {
            // TODO: Construct any child components here
        }

        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            meterorTexture = Game.Content.Load<texture2d>("meteorImg64");
            random = new Random(this.GetHashCode());
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        protected void UpdateMeteorPosition()
        {
            meteorPosition.X = random.Next(Game.Window.ClientBounds.Width - MeterorWidth);
            meteorPosition.Y = 0;
            meteorVelocity.Y = 1 + random.Next(7);
            meteorVelocity.X = random.Next(7) - 1;
        }

        public override void Update(GameTime gameTime)
        {
            if (!GraphicsDevice.Viewport.Bounds.Contains(new Rectangle((int)meteorPosition.X, (int)meteorPosition.Y, meterorTexture.Width, meterorTexture.Height)))
            {
                UpdateMeteorPosition();
            }
            meteorPosition += meteorVelocity;
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            if (meteorPosition == Vector2.Zero && meteorVelocity == Vector2.Zero)
                UpdateMeteorPosition();
            spriteBatch.Begin();
            spriteBatch.Draw(meterorTexture, meteorPosition, Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }

        public bool CheckCollision(Rectangle rect)
        {
            Rectangle spriterect = new Rectangle((int)meteorPosition.X, (int)meteorPosition.Y, MeterorWidth, MeterorHeight);
            return spriterect.Intersects(rect);
        }
    }

as you can notice we are randomly creating a meteor and keep it moving on screen with its velocity which is randomly decided.

Finally we can create our game1.cs class which will join these componants and keep updating the game.

public class SpaceGame : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D galaxyBackImage;
        SpaceShip ship=null;
        const int MeteorCount = 5;
        const int MeteorUpdateTime = 10000;
        private int lastTickCount;
        int rockCount = 0;
        public SpaceGame()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            //graphics.IsFullScreen = true;
            graphics.PreferredBackBufferWidth = Artifacts.GamePreferedBufferWidth;
            graphics.PreferredBackBufferHeight = Artifacts.GamePreferedBufferHeight;

            //graphics.ApplyChanges();
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here             
            //if(ship==null)
            //    Components.Add(new SpaceShip(this));
            //Components.Add(new Meteor(this));
            //GameLevel = 1;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            
            Services.AddService(typeof(SpriteBatch), spriteBatch);

            galaxyBackImage = Content.Load<texture2d>("BGI_galaxy");
            
            // TODO: use this.Content to load your game content here
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            KeyboardState keyboard = Keyboard.GetState();
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || (keyboard.IsKeyDown(Keys.Escape)))
                this.Exit();

            if (ship == null)
            {
                StartGame();
            }
            UpdateGame();

            base.Update(gameTime);
        }

        protected void UpdateGame()
        {
            // Check collisions
            bool hasColision = false;
            Rectangle shipRectangle =ship.GetBounds();
            foreach (GameComponent gc in Components)
            {
                if (gc is Meteor)
                {
                    hasColision = ((Meteor)gc).CheckCollision(shipRectangle);
                    if (hasColision)
                    {
                        // BOOM!
                        //explosion.Play();
                        // Remove all previous meteors
                        RemoveAllMeteors();
                        // Let's start again
                        StartGame();

                        break;
                    }
                }
            }
            CheckforNewMeteor();
        }
        private void CheckforNewMeteor()
        {
            if ((System.Environment.TickCount - lastTickCount) > MeteorUpdateTime)
            {
                lastTickCount = System.Environment.TickCount;
                Components.Add(new Meteor(this));
                //newMeteor.Play();
                rockCount++;
            }
        }
        private void RemoveAllMeteors()
        {
            for (int i = 0; i < Components.Count; i++)
            {
                if (Components[i] is Meteor)
                {
                    Components.RemoveAt(i);
                    i--;
                }
            }
        }

        protected void StartGame()
        {
            for (int i = 0; i < MeteorCount; i++)
                Components.Add(new Meteor(this));
            if (ship == null)
            {
                ship = new SpaceShip(this);
                Components.Add(ship);
            }
            ship.RestSpaceShip();
            
            lastTickCount = System.Environment.TickCount;
            rockCount = MeteorCount;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();
            spriteBatch.Draw(galaxyBackImage, new Rectangle(0, 0, graphics.GraphicsDevice.DisplayMode.Width, graphics.GraphicsDevice.DisplayMode.Height), Color.White);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

    public class Artifacts
    {
        public const int GamePreferedBufferHeight=600;
        public const int GamePreferedBufferWidth=800;

    }

as you can see we have added componants in our game.

Let's understand some basics about these classes.

GraphicsDeviceManager is responsible for drawing objects on your screen. Its created and added into our game1.cs class.

SpriteBatch will be responsible for drawing images on screen. It will accept an graphic device object. SpriteBatch will have a Draw method for drawing images and DrawString method for drawing texts.

As you can see in code SpriteBatch accepting a Texture2D object which is nothing but out image, a position of image where to draw it on screen.

Its very simple code, you can directly copy paste it and use in your project. There is some method in meteor class for colision detection with space ship too.

You can dig deep copy paste code and explore it.

Till then Happy Coding.

Points of Interest

Its awesome fun developing games, I love exploring each and every item.

I learnd all these stuff from Begining XNA 3.0 Game Programing book by Alexandre Santos Lobão, Bruno Evangelista,José Antonio Leal de Farias and Riemer Grootjans.

I got the game idea from book only.

History

19th September 2012 : Added Basic Structure of Fighter Space Ship Game.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here