1

My goal is using intermediate serializer that require Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate but can't change the target framework.

I tried the suggestion in this post: Unable to select Target framework for XNA 4.0 games

but not only it didnt work, it also broke beyond repair my project, I lost all the content folder references...

Community
  • 1
  • 1
user3161621
  • 75
  • 2
  • 8
  • What do you need to achive with Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate? – Wallstrider Mar 21 '14 at 12:53
  • like i wrote above i wanted to use intermediateserializer but since its so complicated im thinking now to give up – user3161621 Mar 21 '14 at 13:58
  • I meant you need "read" or "write" xml files?. Or what kind of operations you need (methods classes) for an instance? If you just need to "read" intermediate xml files then you don't need to use this namespace at all. – Wallstrider Mar 21 '14 at 15:42
  • well at some point i will have to write too but yeah for not i need mainly to read, i get your point... the problem is i have no idea how to write my xml if i dont write it once first... its pretty complicated classes with arrays/lists... i have no clue howi to get the first xml – user3161621 Mar 21 '14 at 16:36
  • Right click on your XNA content project -> Add new item, then just simply select an XML file. Then you must to read how an XML construct [here](http://blogs.msdn.com/b/shawnhar/archive/2008/08/12/everything-you-ever-wanted-to-know-about-intermediateserializer.aspx). – Wallstrider Mar 21 '14 at 17:03
  • If you need to read your xml file then just look at following example: `Content.Load("level");` – Wallstrider Mar 21 '14 at 17:44
  • sry i dont get your example, and yes i knew that blog but it really doesnt give a clue as to how build a complicated xml class to serialize anyway if not intermediate serialization to serialize data, what to use with xna? – user3161621 Mar 21 '14 at 20:20
  • Ok I will provide you an example. Answer soon :D – Wallstrider Mar 21 '14 at 21:54

2 Answers2

1

First of all to force an intermediate serializer work we need to create some class which will be a pattern. But we must understand that the XML files will be inside the content project so we need a reference from the content project to our pattern. But if we will make class (pattern) inside our main project which contains our Game.cs it will has a circular dependency because our main project already referenced to the content project. Thus we must to add a new XNA game library (library's name GameObject). After that we are going to make pattern (class) inside our library. It looks like following:

namespace GameObjects
{
    public class GameSprite
    {
        public string Name { get; set; }
        public Vector2 Position { get; set; }
        public string TexturePath { get; set; }
    }
}

Very simple class will contain all necessary data about future sprite. After that we must to make our XML file which will contain GameSprite data we put in the future into a field of type GameSprite. The XML file looks:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="GameObjects.GameSprite">
    <Name>Apple</Name>
    <Position>320 160</Position>
    <TexturePath>red_apple</TexturePath>
  </Asset>
</XnaContent>

Now we are going to add reference to our XNA library which contains GameSprite class from our main project and content project as well. Then we add new class Sprite.cs which will serve as our final sprite with all logic and texture. For the example I added only Texture to that class and Draw method:

 using GameObjects;

 namespace WindowsGameHelp2
 {
    public class Sprite
    {
        public GameSprite Data { get; private set; }
        public Texture2D Texture { get; private set; }
        public Sprite(string path, ContentManager content)
        {
            // Here we are loading our XML file.
            Data = content.Load<GameSprite>(path);
            Texture = content.Load<Texture2D>(Data.TexturePath);
        }
        public void Draw(SpriteBatch sprite_batch)
        {
            sprite_batch.Draw(Texture, Data.Position, null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);
        }
    }
}

Finally how looks our Game.cs of a main project:

using GameObjects;

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

        Sprite apple;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        protected override void Initialize()
        {
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            //@"Fruits\Apple" is a path to our XML file.
            apple = new Sprite(@"Fruits\Apple", Content);
        }
        protected override void UnloadContent()
        {
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            apple.Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

The output: apple

You can download my example here

EDIT:

Arrays can be serialized and deserialized as well. I added int[] Nutrients to GameSprite as shown below:

namespace GameObjects
{
    public class GameSprite
    {
        public string Name { get; set; }
        public Vector2 Position { get; set; }
        public int[] Nutrients { get; set; }
        public string TexturePath { get; set; }
    }
}

Then I added some new fruits, here is how look our XML files:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="GameObjects.GameSprite">
    <Name>Banana</Name>
    <Position>160 160</Position>
    <Nutrients>10 15 25 35 78</Nutrients>
    <TexturePath>banana</TexturePath>
   </Asset>
</XnaContent>

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="GameObjects.GameSprite">
    <Name>Orange</Name>
    <Position>480 160</Position>
    <Nutrients>40 30 10 30 80</Nutrients>
    <TexturePath>orange</TexturePath>
  </Asset>
</XnaContent>

And you asked how would you use GameSprite[] or List<GameSprite>. Here is how:

namespace GameObjects
{
    public class FruitShop
    {
        public List<GameSprite> Fruits { get; set; }
    }
}

Above I made kinda new class which will contain all our fruits. I put it into our XNA game library and named it FruitShop. Thus I can show you now how it will look in our future XML:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="GameObjects.FruitShop">
    <Fruits>
      <Item>
        <Name>Orange</Name>
        <Position>480 160</Position>
        <Nutrients>40 30 10 30 80</Nutrients>
        <TexturePath>orange</TexturePath>
      </Item>
      <Item>
        <Name>Apple</Name>
        <Position>320 160</Position>
        <Nutrients>50 20 20 30 70</Nutrients>
        <TexturePath>red_apple</TexturePath>
      </Item>
      <Item>
        <Name>Banana</Name>
        <Position>160 160</Position>
        <Nutrients>10 15 25 35 78</Nutrients>
        <TexturePath>banana</TexturePath>
      </Item>
    </Fruits>
  </Asset>
</XnaContent>

Then I made some Shop.cs in our main XNA project which will consume our FruitShop.cs data:

using GameObjects;

namespace WindowsGameHelp2
{
    public class Shop
    {
        private SpriteFont font;

        public FruitShop Data { get; private set; }
        public List<Texture2D> Texture { get; private set; }
        public Shop(string path, ContentManager content)
        {
            font = content.Load<SpriteFont>(@"Fonts\Default");

            Data = content.Load<FruitShop>(path);
            Texture = new List<Texture2D>();

            for (byte i = 0; i < Data.Fruits.Count; i++)
                Texture.Add(content.Load<Texture2D>(Data.Fruits[i].TexturePath));
        }
        public void Draw(SpriteBatch sprite_batch)
        {
            for (byte i = 0; i < Data.Fruits.Count; i++)
            {
                sprite_batch.Draw(Texture[i], Data.Fruits[i].Position, null, Color.White, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);
                sprite_batch.DrawString(font, "|Name: " + Data.Fruits[i].Name + "|", Data.Fruits[i].Position + new Vector2(6, 128), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);
                for (byte x = 0; x < Data.Fruits[i].Nutrients.Length; x++)
                    sprite_batch.DrawString(font, "|Nutrient: " + Data.Fruits[i].Nutrients[x].ToString() + "|", Data.Fruits[i].Position + new Vector2(6, 128 + 20 * (x + 1)), Color.Black, 0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 0.0f);
            }
        }
    }
}

Finally how looks our Game.cs:

using GameObjects;

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

        Shop shop;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        protected override void Initialize()
        {
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            shop = new Shop(@"Shops\FruitShop", Content);
        }
        protected override void UnloadContent()
        {
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            shop.Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

And output: fruits

You can download edited project WindowsGameHelp2 (edit1) here.

In addition if you want to know how to deserialize list of lists or list of dictionaries then this link might be helpful.

Community
  • 1
  • 1
Wallstrider
  • 856
  • 1
  • 7
  • 22
  • thnx, very helpful, even though a have yet a few questions what happens to arrays? lets say my apple has another field Nutrients int[10] would it be deserialized just in a row with spaces like 50 20 20 30 70 ? and last but not least if i have instead of apple a Sprite fruits = new Sprite[100] or a list would it work same way? – user3161621 Mar 22 '14 at 09:20
  • great, you are a life saver – user3161621 Mar 22 '14 at 18:43
0

I had to do this not too long ago, though I did this through Visual Studio 2010 rather than editing the .xml file directly.

Please try the following:

  1. Rollback to your last backup. If you haven't been making backups (shame on you!), try to undo the changes manually
  2. In Visual Studio, right-click on your project and select 'Properties'
  3. On the 'Application' tab, set the target framework to .NET Framework 4

Hope this helps.

  • nope, this is the cause of the problem :P the target framework menu is grayed out and we cant do nothing about it – user3161621 Mar 21 '14 at 11:59
  • Hmmm... the box wasn't grayed out for me, I'm afraid I don't know why it is for you and other users. Try creating a new test XNA project and see if the box is grayed out for it? – user3256944 salutes Monica Mar 21 '14 at 12:46
  • yes it is, as far as i remember, the reason is that that library is not usable by third parts or something, i remember ppl saying that you couldnt distribute the dll associated – user3161621 Mar 21 '14 at 13:22
  • I'm sorry, I can't replicate what you guys are experiencing. I hope someone else in the XNA community can help you. – user3256944 salutes Monica Mar 21 '14 at 13:48