C# XNA 4.0 How to serialize a 2D array?

Started by
44 comments, last by Shawn Naef 6 years, 1 month ago

public struct SaveGame
    {
        // Player Variables
        public int PlayerScore;
        public int PlayerFuel;
        public int PlayerMaxFuel;
        public int PlayerPickTier;
        public int PlayerInvTier;
        public int PlayerFuelTier;
        public int PlayerMaxDepth;
        public int PlayerCoin;
        public int PlayerInv;
        public int PlayerMaxInv;
        public int PlayerDepth;
        public int PlayerPosition;
        // Player Inventory Variables
        public int PlayerInventoryCoalOre;
        public int PlayerInventoryCopperOre;
        public int PlayerInventoryTinOre;
        public int PlayerInventoryIronOre;
        public int PlaceHolder;
        // Player Statistics
        public int TotalMoneyAquired;
        public int TotalUpgradesAquired;
        public int TotalMovesMade;
        public int TotalFuelUsed;
        public int TotalBlocksMined;
        public int TotalDirtBlocksMined;
        public int TotalCoalOre;
        public int TotalCopperOre;
        public int TotalTinOre;
        public int TotalIronOre;
        // Game Map Array
        //public int[,] tileMap0;
    }

Save Game Container

 

Save Game Initate


private void InitiateSave()
        {
            if (!Guide.IsVisible)
            {
                device = null;
                StorageDevice.BeginShowSelector(PlayerIndex.One, this.SaveToDevice, null);
            }
        }

 

Save Game Code


void SaveToDevice(IAsyncResult result)
        {
            device = StorageDevice.EndShowSelector(result);
            if (device != null && device.IsConnected)
            {
                SaveGame SaveData = new SaveGame()
                {
                    // Player Variables
                    PlayerScore = PlayerScore,           
                    PlayerFuel = PlayerFuel,
                    PlayerMaxFuel = PlayerMaxFuel,
                    PlayerPickTier = PlayerPickTier,
                    PlayerInvTier = PlayerInvTier,
                    PlayerFuelTier = PlayerFuelTier,
                    PlayerMaxDepth = PlayerMaxDepth,
                    PlayerCoin = PlayerCoin,
                    PlayerInv = PlayerInv,
                    PlayerMaxInv = PlayerMaxInv,
                    PlayerDepth = PlayerDepth,
                    PlayerPosition = PlayerPosition,
                    // Player Inventory Variables
                    PlayerInventoryCoalOre = PlayerInventoryCoalOre,
                    PlayerInventoryCopperOre = PlayerInventoryCopperOre,
                    PlayerInventoryTinOre = PlayerInventoryTinOre,
                    PlayerInventoryIronOre = PlayerInventoryIronOre,
                    PlaceHolder = PlaceHolder,
                    // Player Statistics
                    TotalMoneyAquired = TotalMoneyAquired,
                    TotalUpgradesAquired = TotalUpgradesAquired,
                    TotalMovesMade =  TotalMovesMade,
                    TotalFuelUsed = TotalFuelUsed,
                    TotalBlocksMined = TotalBlocksMined,
                    TotalDirtBlocksMined = TotalDirtBlocksMined,
                    TotalCoalOre = TotalCoalOre,
                    TotalCopperOre = TotalCopperOre,
                    TotalTinOre = TotalTinOre,
                    TotalIronOre = TotalIronOre,
                    // Game Map Array
                    //tileMap0 = ,
                };
                IAsyncResult r = device.BeginOpenContainer(containerName, null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = device.EndOpenContainer(r);
                if (container.FileExists(filename))
                    container.DeleteFile(filename);
                Stream stream = container.CreateFile(filename);
                XmlSerializer serializer = new XmlSerializer(typeof(SaveGame));
                serializer.Serialize(stream, SaveData);
                stream.Close();
                container.Dispose();
                result.AsyncWaitHandle.Close();
                gameState = GameState.GameScreen;
            }
            else
            {
                gameState = GameState.GameMenuScreen;
            }
        }

 

2D Array I Wish To Include With The Above Save

 


int[,] tileMap = new int[,]
        {
            { 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 7, 8, 1, 1, 1, 1, 1, 1, 1, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
            { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, },
        };

 

I'm wondering if anyone can help me convert a 2D array into a format that is compatible with my serialization save. Thanks

Advertisement

I haven't used C# and .NET in awhile, especially XNA since it was dropped back in 2013 or was it 2014?... I would highly recommend moving to MonoGame which is a re-implementation of XNA, or another framework.

To answer your question, you can use XmlSerializer.

https://docs.microsoft.com/en-us/dotnet/standard/serialization/introducing-xml-serialization

https://docs.microsoft.com/en-us/dotnet/standard/serialization/examples-of-xml-serialization

Again, I haven't used C# in forever, but I recall you cannot use this method to serialize 2D arrays [ , ] but you can use them on jagged arrays [][].

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/jagged-arrays

This should be what you're looking for.

 

Programmer and 3D Artist

Well XNA is what I've learned to use and am still learning so. I tried porting a project over and it failed miserably and broke it some of the stuff i am using isn't even compatible. There is a way it needs to be unzipped into a single array and then serialized. . Now as for serialization I'm already exporting to an XML with the code above. Does anyone know to convert my array to 1D and save / opposite process for the load too?

 

 

@Rutin thanks for trying to help.

For the record the array has to be 2D and can not be jagged. This is a map for a vertical scrolling game and it renders tile by tile.

All you have to do is convert your 2D Array to a Jagged Array, then serialize it. When you're bringing it back, just convert your Jagged to a 2D Array.

Programmer and 3D Artist

Could you show me a sample of code?

33 minutes ago, Shawn Naef said:

Could you show me a sample of code?

I made a quick example showing how to load 2D into Jagged, and Jagged into 2D with console print.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 2D Array
            int[,] my2DArray = new int[5, 5] {
                { 1, 2, 3, 4, 5 },
                { 6, 7, 8, 9, 10 },
                { 11, 12, 13, 14, 15 },
                { 16, 17, 18, 19, 20 },
                { 21, 22, 23, 24, 25 }
                };

            // Jagged Array
            int[][] myJaggedArray = new int[5][];
            for (int num = 0; num < 5; num++)
            {
                myJaggedArray[num] = new int[5];
            }

            // Load 2D into Jagged
            for (int col = 0; col < 5; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    myJaggedArray[col][row] = my2DArray[col, row];
                }
            }

            // Divider
            Console.WriteLine("=========== 2D ARRAY ============");

            // Print 2D Array
            for (int col = 0; col < 5; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    if (row != 4)
                    {
                        Console.Write(my2DArray[col, row] + ", ");
                    } else
                    {
                        Console.Write(my2DArray[col, row] + "\n");
                    }
                }
            }

            // Divider
            Console.WriteLine("\n\n\n===========JAGGED ARRAY============");


            // Print Jagged Array
            for (int col = 0; col < 5; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    if (row != 4)
                    {
                        Console.Write(myJaggedArray[col][row] + ", ");
                    }
                    else
                    {
                        Console.Write(myJaggedArray[col][row] + "\n");
                    }
                }
            }

            // Divider
            Console.WriteLine("=======================\n\n");

            // Load Jagged into 2D
            int[,] new2DArray = new int[5, 5];

            for (int col = 0; col < 5; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    new2DArray[col, row] = myJaggedArray[col][row];
                }
            }

            // Divider
            Console.WriteLine("=========== NEW 2D ARRAY ============");

            // Print 2D Array
            for (int col = 0; col < 5; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    if (row != 4)
                    {
                        Console.Write(new2DArray[col, row] + ", ");
                    }
                    else
                    {
                        Console.Write(new2DArray[col, row] + "\n");
                    }
                }
            }


            // Wait
            Console.ReadLine();

        }
    }
}

 

Programmer and 3D Artist

Maybe we can make this even easier. Why not convert my infinite to a jagged and i can just adjust the internal size as i expand it. ill post a sample of my writing code

 


int tileMapWidth = tileMap.GetLength(1);
                int tileMapHeight = tileMap.GetLength(0);

                for (int x = 0; x < tileMapWidth; x++)
                {
                    for (int y = 0; y < tileMapHeight; y++)
                    {
                        int textureIndex = tileMap[y, x];
                        Texture2D texture = tileTextures[textureIndex];

                        spriteBatch.Draw(
                            texture,
                            new Rectangle(
                                x * tileWidth - cameraPositionX,
                                y * tileHeight - cameraPositionY,
                                tileWidth,
                                tileHeight),
                            Color.White);
                    }
                }

 

Does it need to be saved as Xml? Can you serialize it to binary and then just store it along side your save file? something like saveName.map or something?

I guess if it can be incorporated into my existing load code. The array is serving 2 purposes 1 it tells the engine which textures to draw so that i don't have to hard code it. Second I'm also using it to track "mined out 'air'" blocks as well as collision solely based on which tile the value of which is in the array.

 

 

To help give you an idea of how my code is being used and a better understanding. Here is a screenshot of my game.

 

n53afm.jpg

This topic is closed to new replies.

Advertisement