views:

193

answers:

3

Let's say I have my class Level:

public class Level
{
    public Vector2 dogStart;
    public List<Pickup> pickups;
    public string backgroundAsset;

    public Level()
    {
        pickups = new List<Pickup>();
    }
}

How do I store/load instances of the Level class? XML files? Do I create class LevelOne, class LevelTwo, etc. and hardcode? What's the recommended way in XNA?

This is also assuming I don't really have time for an editor, so for instance XML would be really handy for me to be able to type by hand. But in the case of XML, how would I do that? What system would I use to load an XML file into an instance of class Level?

A: 

Hardcoding classes would probably make it harder to extend your game, you would have to code each level. XML is a fairly good approach since the amount of data for each level is probably small.

You can use the Linq-to-XML XElement to load XML data. These classes are supported in the XNA Framework 3.0 and newer.

Peter Lillevold
A: 

However you want; see any article on "data serialization."

If you want something human readable, CSV is another common, very simple file-format for storing levels.

BlueRaja - Danny Pflughoeft
+1  A: 

I ended up using the XmlSerializer class.

I started by creating one root data class; our game was called Outrage so I named it OutrageGameInstance. This class had one instance of Dog (our main character), a List of possible pickup item types, and a List of levels. Each of these structures had other data variables. Any variables that I didn't want in the XML file, I just wrote [NonSerializable] in the line above the variable declaration. I also found out through experimentation that only public variables are serialized, so I could hide things in private variables.

Anyway, I commented out the usual bit in Program.cs and put in some code to create an example instance of OutrageGameInstance, and then serialized it using XmlSerializer. This gave me a file that I could then tweak by hand, and as you see below the syntax is real easy to understand and add to. I switched back the Program.cs file, and put the XML file into the Content project. In the properties for the XML file, change the build action to 'none' (compile made errors) and set it to always copy to output directory.

Then it's just a matter of using an XmlSerializer to deserialize the XML file in the Initialize function of the Game class, and use the data however you want!

This was my data file, just to show you how easy it was to edit:

<?xml version="1.0" encoding="utf-8"?>
<OutrageGameInstance xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  <dog>
    <scale>
      <X>0.3</X>
      <Y>0.3</Y>
    </scale>
  </dog>
  <pickupTypes>
    <PickupType>
      <picture>Bone</picture>
      <collideSound>BoneMunch</collideSound>
      <animationType>none</animationType>
      <scoreValue>5</scoreValue>
      <scale>
        <X>0.3</X>
        <Y>0.3</Y>
      </scale>
    </PickupType>

  </pickupTypes>
  <levels>
    <Level>
      <playerStart>100</playerStart>
      <dogHead>Level1/dog_head</dogHead>
      <dogTail>Level1/dog_tail</dogTail>
      <floor>668</floor>
      <name>Flowers!</name>
      <background>Level1/background</background>
      <foreground>Level1/foreground</foreground>
      <pickupInstances>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>50</X>
            <Y>50</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>850</X>
            <Y>50</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>300</X>
            <Y>250</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>600</X>
            <Y>250</Y>
          </location>
        </PickupInstance>

      </pickupInstances>
      <gravity>0.3</gravity>
      <backgroundMusic>BackgroundMusic1</backgroundMusic>
      <madMeter>Level1/thermo_happy</madMeter>
    </Level>
    <Level>
      <playerStart>100</playerStart>
      <dogHead>Level1/dog_head</dogHead>
      <dogTail>Level1/dog_tail</dogTail>
      <floor>668</floor>
      <name>Flowers!</name>
      <background>Level1/background</background>
      <foreground>Level1/foreground</foreground>
      <pickupInstances>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>50</X>
            <Y>250</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>850</X>
            <Y>250</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>300</X>
            <Y>50</Y>
          </location>
        </PickupInstance>
        <PickupInstance>
          <type>Bone</type>
          <location>
            <X>600</X>
            <Y>50</Y>
          </location>
        </PickupInstance>

      </pickupInstances>
      <gravity>0.3</gravity>
      <backgroundMusic>BackgroundMusic1</backgroundMusic>
      <madMeter>Level2/thermo_inshock</madMeter>
    </Level>

  </levels>
</OutrageGameInstance>
Ricket
Extending this answer even further, I experimented with Xbox 360 games over this past weekend and found that, as long as the XML files are put into the Content pipeline (and set to copy to output always), they get deployed and can be read on the Xbox!
Ricket