Archive for January 2011

Reading XML file data in an XNA game

The question of how to read XML files seems to come up multiple times every day on the AppHub forums. For most games, using the Content pipeline is overkill. Fortunately, there’s an easier way – LINQ to XML.

Say you’re working on a dungeon crawler and you’ve got an XML file that describes rooms in the dungeon:

<?xml version="1.0" encoding="utf-8" ?> 
<Rooms> 
  <Room> 
    <id>1</id> 
    <width>10</width> 
    <height>10</height> 
    <locationx>2</locationx> 
    <locationy>3</locationy> 
    <items> 
      <item> 
        <id>5</id> 
        <locationx>3</locationx> 
        <locationy>7</locationy> 
      </item> 
    </items> 
  </Room> 
  <Room> 
    <id>2</id> 
    <width>5</width> 
    <height>5</height> 
    <locationx>15</locationx> 
    <locationy>25</locationy> 
    <items> 
      <item> 
        <id>2</id> 
        <locationx>1</locationx> 
        <locationy>1</locationy> 
      </item> 
    </items> 
  </Room> 
</Rooms>

So you’ve added this file containing this data to your Content project. Make sure you change the Build Action for the file to Content and the Copy to Output Directory to Copy always.

How do you get this data into some objects that are easy to work with in your code. One simple way would be to create two classes:

    public class Room
    {
        public int id { get; set; }
        public int width { get; set; }
        public int height { get; set; }
        public int locationx { get; set; }
        public int locationy { get; set; }
        public List<Item> items { get; set; }
    }

    public class Item
    {
        public int id { get; set; }
        public int locationx { get; set; }
        public int locationy { get; set; }
    }

All that needs to be done to get this data into a list of Room objects is:

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Storage;

namespace Xbox360Game1
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        List<Room> rooms;

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

        protected override void Initialize()
        {
            System.IO.Stream stream = TitleContainer.OpenStream("Content\\Rooms.xml");

            XDocument doc = XDocument.Load(stream);

            rooms = new List<Room>();

            rooms = (from room in doc.Descendants("Room")
                       select new Room()
                        {
                            id = Convert.ToInt32(room.Element("id").Value),
                            width = Convert.ToInt32(room.Element("width").Value),
                            height = Convert.ToInt32(room.Element("height").Value),
                            locationx = Convert.ToInt32(room.Element("locationx").Value),
                            locationy = Convert.ToInt32(room.Element("locationy").Value),
                            items = (from i in room.Descendants("item")
                                     select new Item()
                                     {
                                         id = Convert.ToInt32(i.Element("id").Value),
                                         locationx = Convert.ToInt32(i.Element("locationx").Value),
                                         locationy = Convert.ToInt32(i.Element("locationy").Value)
                                     }).ToList()
                        }).ToList();


            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

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

            base.Update(gameTime);
        }

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

            base.Draw(gameTime);
        }
    }
}

 

The only problem with using LINQ to XML, that I haven’t figured out a way around, is that debugging the query is basically impossible. If you don’t have the query exactly right you’ll get an error and you may not know what the problem is. In my case some missing parentheses in getting the Items list set up correctly caused me some problems and it wasn’t immediately obvious why. Part of that is probably my n00bness in using LINQ. Hopefully Microsoft will come up with a way, if it doesn’t already exist, to make debugging easier.

Music sample for Dream Build Play game

While not final nor complete by any means, I figured I hadn’t posted anything in a while so why not throw this up (maybe I should have said “put this out”. Wait, make that “let people have a listen”. Yeah, that’s better! :D). I’m shooting for a mix of metal and possibly some industrial type music for the game.

Note: Uses Flash player, you may need to turn your speakers way down 🙁

DBP Game Progress

While progress on the game I’m working on hasn’t been as quick as I’d hoped, I think I’m still doing ok since it’ll be at least February until we know when the actual deadline will be. I’m thinking we’ll have until at least April or May to get a game done.

I’m hoping to have the developer level editor done by this weekend and a test level completed. You may be saying “Why did he say ‘developer level editor?’ That would be because the game will feature, among other things, an in-game level editor and level sharing. Some of the other features that are being planned:

  • Single and multiplayer support
  • 4 game modes
  • Badges (XBLIG’s version of Achievements)
  • “Global” leaderboards (using the fantastic Highscores Component)
  • Customizable/upgradeable features for in-game “characters” using in-game winnings (one of the things tracked in the leaderboards) from game matches. Yes, that’s pretty vague. More to come. 😀
  • In-game Auction/Marketplace for buying/selling game objects (again using a variation of the Highscores Component). This one will be tricky however and may not make the final version (unless I win and the game becomes an XBLA game!)

I’m pretty excited about the possibilities for the game. Even if I don’t win, it’ll be put on XBLIG and hopefully be the first step to becoming a full-time indie game dev career. 🙂

Another Year, Another Try At Getting It Right

OK, I guess 3rd (or is this 4th, 5th, …) time is the charm. Maybe since I’m now using a decent blogging engine, I’ll be more likely to keep it up to date.

Here’s my list of tech-related New Years Resolutions:

  • Get a game in this year’s Dream Build Play competition (in-progress)
  • Post some useful XNA/WP7 related information/code snippets/samples on this blog (more than once every half-dozen months)
  • Get a game (or two, either my DBP entry or another) on XBLIG to get some money coming in to get a nest egg so I can start doing game development full time.

That’s a short, but difficult list. Let’s see how well I do. For the 2nd one I need some suggestions as to what to blog about since I’m not ready to talk about the DBP game. I’m thinking about posting some thoughts on the general state of XBLIG and WP7. There’s been a lot going on, not all of it good. I could probably do a series of posts on it, but that might be going a bit far. We’ll see I guess.

In other news, I was renewed for another year as a Microsoft MVP. This is my 5th straight year. I’ll be heading back to Microsoft at the end of the next month to chat with the XNA, and hopefully Windows Phone 7, people to see what’s going on with things. Hopefully they’ll have some good info to share with us as to what’s coming up for both areas. Also hopefully by that time I’ll have a WP7 to take with me and get some good photos/videos. I’m just waiting for Sprint to come out with their phone.