skip to main | skip to sidebar

Breaking Builds Since 2008

Pages

  • Home

Saturday, 16 July 2011

Hero source code

This is the sample XNA code for creating a Hero character in a computer game; which I talked about my previous posts.  Make sure you read those first to find out whats going on.

(Disclaimer:  I wouldn't normally have this many comments cluttering my code.)


using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
 
namespace Blog.Drawing.Actors
{
    /// <summary>
    /// An image of a hero.
    /// He can run, jump and fall.
    /// </summary>
    public class Hero : DrawableGameComponent
    {
        private const int NumberOfFrames = 5;
        private Texture2D Image;
        private Vector2 Position = new Vector2(0f, 200f);
        private Rectangle CurrentFrame;
        private SpriteBatch SpriteBatch;
        private List<Rectangle> Frames = new List<Rectangle>();
        private float VelocityX = 10;
        private float VelocityY = 0;
        private Game CurrentGame; 
        private Random Random = new Random();
 
        public Hero(Game game): base(game)
        {
            CurrentGame = game;
        }
 
 
 
        /// <summary>
        /// Initializes the component. 
        /// Override this method to load any non-graphics resources 
        /// and query for any required services.
        /// </summary>
        public override void Initialize()
        {
            // Add frames.
            // Assumes the image file shows five heros stood side by side.
            // It uses rectangles to show where to crop the image.
 
            const int width = 75;
            const int height = 111;
 
            for (int ii = 0; ii < NumberOfFrames; ii++)
            {
                Rectangle frame = new Rectangle()
                {
                    X = width * ii,
                    Y = 0,
                    Width = width,
                    Height = height
                };
                Frames.Add(frame);
            }
 
            CurrentFrame = Frames[0];
            base.Initialize();
        }
 
 
 
 
        /// <summary>
        /// Called when graphics resources need to be loaded. 
        /// Override this method to load any component-specific 
        /// graphics resources.
        /// </summary>
        protected override void LoadContent()
        {
            // Load the image of the hero
            Image = CurrentGame.Content.Load<Texture2D>("hero");
 
            // Get the current spritebatch.  
            // This will be used later to draw the images.
            SpriteBatch = (SpriteBatch)CurrentGame.Services.GetService(
                typeof(SpriteBatch));
 
            base.LoadContent();
        }
 
 
 
        /// <summary>
        /// Keeps track of if it is time to update the Hero yet.
        /// </summary>
        private ElapsedTime UpdateElapsedTime = new ElapsedTime(100);
 
 
 
 
        /// <summary>
        /// Called when the GameComponent needs to be updated. 
        /// Override this method with component-specific update code.
        /// </summary>
        public override void Update(GameTime gameTime)
        {
            // If enough time has passed then we are ready to update the hero.
            if (UpdateElapsedTime.Ready(gameTime))
            {
                // Apply the force of gravity
                VelocityY += 100f;
 
                // Stop him from falling off the bottom of the screen
                if (Position.Y > 400f && VelocityY > 0f)
                {
                    VelocityY = 0f;
                }
 
                // Made him jump every now and then:
                if (this.Random.Next(30) == 0) 
                {
                    VelocityY -= 100f;
                }
 
                // Update his position based on his speed
                Position = new Vector2(
                    Position.X + VelocityX,
                    Position.Y + VelocityY
                );
 
                // Display one of the hero images at random
                // This will make it look as if he is running
                CurrentFrame = Frames[this.Random.Next(NumberOfFrames)];
            }
 
            base.Update(gameTime);
        }
 
 
 
        /// <summary>
        /// Called when the DrawableGameComponent needs to be drawn. 
        /// Override this method with component-specific drawing code. 
        /// Reference page contains links to related conceptual articles.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            //Draw the hero
            SpriteBatch.Draw(Image, Position, CurrentFrame, Color.White);
            base.Draw(gameTime);
        }
    }
 
 
 
 
 
    /// <summary>
    /// Keeps track of the passing of time.
    /// </summary>
    public class ElapsedTime
    {
        private TimeSpan Total;
        private readonly TimeSpan RefreshInterval;
 
        /// <summary>
        /// Keeps track of the passing of time.
        /// </summary>
        /// <param name="milliseconds">
        /// The ammount of it should wait for before declaring itself ready.
        /// </param>
        public ElapsedTime(int milliseconds)
        {
            RefreshInterval = TimeSpan.FromMilliseconds(milliseconds);
        }
 
        /// <summary>
        /// Updates the internal timer and shows if sufficient time has passed.
        /// </summary>
        public bool Ready(GameTime gameTime)
        {
            Total += gameTime.ElapsedGameTime;
 
            if (Total > RefreshInterval)
            {
                Total -= RefreshInterval;
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
Posted by Mike at 06:39 0 comments Email This BlogThis! Share to X Share to Facebook
Labels: XNA

Playing around with my first game

First of all, put on your headphones and watch this:


As it is my first game let’s assume from the outset that it will not be commercial. Even though XNA games can easy support the XBox360 and Windows Phone 7, mine is going to target only the PC.  I don’t own either of these and I they would just slow me down without really adding anything new.

Creating a revolutionary new concept from scratch is probably a bit extreme for a first outing so it will be based on some classic favorites of gaming.

The concept is that the man has fallen down to the bottom of the well has to jump around to stay on top of the falling bricks, before fighting his way out and raising the flag. Otherwise he will be overwhelmed and crushed to death.

An hour in Photoshop creates a few images to work with.

I'm not going to try to teach you all of XNA but here are a few bits I found interesting.  XNA follows a cycle, similar to the ASP.NET page life-cycle.  Game are made of "GameComponents", such as images and audio files.  When you want to create a new image you just need to inherit from DrawableGameComponent and override four methods.  The framework then will call these at the appropriate times.
public virtual void Initialize()
protected virtual void LoadContent()
public virtual void Update(GameTime gameTime)
public override void Draw(GameTime gameTime)
Time for some code. Take a quick look at my next post for an example class of our Hero character.  You don't have to read it all, but just take a quick look and see how small the file is. Pretty small considering he can run, jump and fall down with realistic gravity.  He also has five different poses to give the appearance of movement.

If you do read it, you'll see that nothing here is really that hard.  Most of it is regular .NET. The only confusing bits are the new types; Texture2D and SpriteBatch.  But you don't really have to interact with these very much.  You could just put these two into a base class shared by all your images, and then forgot about them.  You can't even tell that we are using DirectX.



To highlight the Update method:
        private ElapsedTime UpdateElapsedTime = new ElapsedTime(100);
 
        public override void Update(GameTime gameTime)
        {
            // If enough time has passed then we are ready to update the hero
            if (UpdateElapsedTime.Ready(gameTime))
            {
                // Do the speed and position etc....
            }
        }

This is interesting because it means that the updating code will not run at every opertunity.  I will only run every 100ms (or ten times per second).  So if the computer is very powerful the game will not runaway and become too fast.  Similarly if the computer temporarily runs slowly and falls behind on its updates; then it will later update more frequently to compensate.  This means that you get a consistent gaming experiance, dispite the level of your machine.

It was a little tricky to find the optimum length of time to wait.  At one point I thought making this value smaller would make the game more responsive.  However, this seams to not always be the case.  When I set it to update every 10ms the game started to look jerky.  I think Update() was using up too much time, leaving the XNA framework with no time left to call my Draw() method.  By increasing the wait to 100ms, I found that this was less demanding and allowed Draw() to be called more frequently.



To highlight gravity:
                // Apply the force of gravity
                VelocityY += 100f;
That's it.  To make your monster fall realistically only takes one line of code.  Every time Update() is executed his vertical velocity will increase, resulting in him falling in realistic arc.
Posted by Mike at 06:23 0 comments Email This BlogThis! Share to X Share to Facebook
Labels: XNA

Thursday, 7 July 2011

Is it true?

Recently, while describing to a friend why .NET is such a good development framework, I listed off the usual features. One of my favourites is that once you know C# you have the ability to write websites, desktop apps, phone apps, web-services, games, Silverlight apps, PowerShell etc. for little additional effort. You get all that power from only one language. Better yet, if C# is not for you, there are plenty of other languages to choose from.

This is great for developers, because if you want to make a move in your career you can work on a completely new type of project without having to forget your favourite language or learn everything from scratch.

But this got me wondering, is it really true?

Is it possible to switch over to a different flavour of .NET and just run with it; or find yourself lost in a maze of new features? Am I just repeating the babble heard from other developers without really checking up on them?

Last Christmas (while commuting on the bus to escape the snow) I read up on Microsoft’s hobbyist game development platform, XNA, and that didn't look so bad. Never got around to actually writing any XNA code though, so maybe now is the time. My only experience creating games is a text based football manager game from my C++ days. I have never made a visual game before, so if I am able to then anyone can.

So this is the plan. To create a small PC game, and achieve it within a reasonable timeframe, without it spiraling out of control into some sort of massively multiplayer tragedy. I don't intend to still be trying to finish when I'm sixty. I don't intend to show up for work in the morning with bloody eyes because I've been slaving all hours of the night. I don’t intend to have to study five books as thick as my head. I just want to see what can be achieved by a normal person in a few afternoons.
Posted by Mike at 08:55 2 comments Email This BlogThis! Share to X Share to Facebook
Labels: XNA
Newer Posts Home

About Me

Mike
Keen on all things C#.
View my complete profile

Blog Archive

  • ►  2014 (1)
    • ►  July (1)
  • ►  2013 (1)
    • ►  August (1)
  • ►  2012 (1)
    • ►  March (1)
  • ▼  2011 (5)
    • ►  August (2)
    • ▼  July (3)
      • Hero source code
      • Playing around with my first game
      • Is it true?

Followers

Powered by Blogger.
 
Copyright (c) 2010 Breaking Builds Since 2008. Designed for Video Games
Download Christmas photos, Public Liability Insurance, Premium Themes