0

I've been programming a 2D RPG in XNA using this tutorial series: http://xnagpa.net/xna4rpg.php

The author never finished, but I've continued on and made a lot of progress (collision detection, NPC pathing, inventory, and more). Right now I'm working on an event system (transitioning to a different level, interacting with NPCs, quests and so on). It's very bare bones but this is my initial set up:

public abstract class GameEvent
{
    #region Field Region

    protected Point eventPosition;

    #endregion

    #region Property Region

    public Point EventPosition
    {
        get { return eventPosition; }
    }

    #endregion

    #region Constructor Region

    public GameEvent()
    {

    }

    public GameEvent(Point eventPosition)
    {
        this.eventPosition = eventPosition;
    }

    #endregion
}

public class LevelTransitionEvent : GameEvent
{
    #region Field Region

    public Point teleportPosition;
    public string mapName;

    #endregion

    #region Constructor Region

    public LevelTransitionEvent()
    {

    }

    public LevelTransitionEvent(Point eventPosition, Point teleportPosition, 
        string mapName)
        : base(eventPosition)
    {
        this.teleportPosition = teleportPosition;
        this.mapName = mapName;
    }

    #endregion
}

I use the level editor that was started in the tutorial to make the map, add NPCs and now to add events. The way it works is using XML serialization/deserialziation. It works fine for everything (adding tiles, NPCs, treasure chests) but now I'm trying to add these events, starting with level transition events.

This is the code from the tutorial dealing with serialization:

static class XnaSerializer
{
    public static void Serialize<T>(string filename, T data)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        using (XmlWriter writer = XmlWriter.Create(filename, settings))
        {
            IntermediateSerializer.Serialize<T>(writer, data, null);                
        }
    }

    public static T Deserialize<T>(string filename)
    {
        T data;

        using (FileStream stream = new FileStream(filename, FileMode.Open))
        {
            using (XmlReader reader = XmlReader.Create(stream))
            {
                data = IntermediateSerializer.Deserialize<T>(reader, null);
            }
        }

        return data;
    }
}

Serializing the level:

  XnaSerializer.Serialize<LevelData>(LevelPath + levelData.LevelName + ".xml", levelData);

Right now I'm just trying to get it to work, so I included a simple event:

        levelData.GameEvents.Add(new LevelTransitionEvent(new Point(0,0), new Point(5,5), "temp"));

levelData.GameEvents is a List of GameEvent type.

This is the XML output:

 <?xml version="1.0" encoding="utf-8"?>
 <XnaContent xmlns:WorldClasses="RpgLibrary.WorldClasses"                                                                            xmlns:EventClasses="XRpgLibrary.EventClasses">
 <Asset Type="WorldClasses:LevelData">
 <LevelName>test 6</LevelName>
 <MapName>6</MapName>
 <MapWidth>100</MapWidth>
 <MapHeight>100</MapHeight>
 <Characters />
 <Chests />
 <GameEvents>
  <Item Type="EventClasses:LevelTransitionEvent">
    <teleportPosition>5 5</teleportPosition>
    <mapName>temp</mapName>
  </Item>
</GameEvents>
<TrapNames />
 </Asset>
 </XnaContent>

For some reason, the base class variable, eventPosition, is not being included. Is there some additional feature I have to add to get the base class member data to also include in the xml serialization? Thanks

  • I'm not an expert on XNA, but when using the standard .NET XmlSerializer (to which I would assume the IntermediateSerializer is similar), all properties that are to be serialized / deserialized must have a public getter and setter. Try giving that a shot, and see what that produces. Your other fields are public and because they are fields (though I would make them properties as well) are read and write capable. See here for details on this: http://stackoverflow.com/questions/575432/why-isnt-my-public-property-serialized-by-the-xmlserializer – xDaevax Aug 26 '14 at 18:06
  • You're right, I just changed the eventPosition field to public and it works fine. Thanks for that. I don't want my fields to be public like this, I was just creating temporary classes to test out this new feature. Thanks again! – Robert Joseph Dacunto Aug 26 '14 at 18:18

2 Answers2

1

When using the standard .NET XmlSerializer (to which the IntermediateSerializer is similar), all properties that are to be serialized / deserialized must have a public getter and setter.

See here for details on this: Why isn't my public property serialized by the XmlSerializer?

The MS documentation has a simple tutorial also on serializing game data with XNA here: http://msdn.microsoft.com/en-us/library/bb203924.aspx (note that this uses the XmlSerializer directly).

By changing your property to:

   public Point EventPosition
    {
        get { return eventPosition; }
        set { eventPosition = value; }
    }

you should now see it in the output result of the serialization.

Community
  • 1
  • 1
xDaevax
  • 2,012
  • 2
  • 25
  • 36
0

The IntermediateSerializer, by default, only serializes public fields or properties with both public get and set accessors. To have it serialize less public fields, use the [ContentSerializer] attribute:

[ContentSerializer]
public Point EventPosition
{
    get { return eventPosition; }
}

For more information, see: Everything you ever wanted to know about IntermediateSerializer