Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good example of saving game data in XNA 4.0?

I am trying to work my way through the XNA MSDN documentation on saving and reading game data, and I am not having much luck.

In essence I have a manager class which keeps track multiple instance of base classes.

I want to be able to save the state of the entire list of objects that the manager is keeping track of. Then load them in the next time the game loads. Basically saving the state of the world.

like image 881
NA Slacker Avatar asked Sep 16 '10 02:09

NA Slacker


People also ask

What is XNA data?

In data science there is a concept called Exploratory Data Analysis (EDA).

Is Microsoft XNA a game engine?

XNA Game Studio 4.0 is a programming environment that allows you to use Visual Studio 2010 to create games for Windows Phone, the Xbox 360 console, and Windows-based computers. XNA Game Studio 4.0 includes the XNA Framework 4.0, which is a set of managed libraries designed for game development based on Microsoft .

Is Microsoft XNA still used?

MonoGame is an open source, C# framework that implements the application programming interface (API) of XNA, Microsoft's late game development toolset that was retired in 2013.

What replaced Microsoft XNA?

There are more than 25 alternatives to XNA Game Studio for a variety of platforms, including Windows, Linux, Mac, Android and iPhone. The best alternative is GDevelop, which is both free and Open Source. Other great apps like XNA Game Studio are CRYENGINE, ENIGMA - LateralGM, Torque 3D and Adventure Game Studio.


1 Answers

If you use the XmlSerializer as shown in the XNA 4.0 help, base classes need to have the [XmlInclude(Type)] attribute specified for each concrete type they can be serialized into.

Below is an example of how to save game data in XNA 4.0. Press F1 to save once the game is running. The data will be saved to a location similar to C:\Users\{username}\Documents\SavedGames\WindowsGame\Game1StorageContainer\Player1.

Loading the data again is a very similar process.

To get this working on XBox add references to Microsoft.Xna.Framework.GamerServices & System.Xml.Serialization.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;

namespace WindowsGame
{
    [XmlInclude(typeof(Soldier)), XmlInclude(typeof(Grenade))]
    public class BaseGameObject
    {
        public Vector3 Position { get; set; }
    }

    public class Soldier : BaseGameObject
    {
        public float Health { get; set; }
    }

    public class Grenade : BaseGameObject
    {
        public float TimeToDetonate { get; set; }
    }

    public struct SaveGameData
    {
        public string PlayerName;
        public Vector2 AvatarPosition;
        public int Level;
        public int Score;
        public List<BaseGameObject> GameObjects;
    }

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        enum SavingState
        {
            NotSaving,
            ReadyToSelectStorageDevice,
            SelectingStorageDevice,

            ReadyToOpenStorageContainer,    // once we have a storage device start here
            OpeningStorageContainer,
            ReadyToSave
        }

        GraphicsDeviceManager graphics;
        KeyboardState oldKeyboardState;
        KeyboardState currentKeyboardState;
        StorageDevice storageDevice;
        SavingState savingState = SavingState.NotSaving;
        IAsyncResult asyncResult;
        PlayerIndex playerIndex = PlayerIndex.One;
        StorageContainer storageContainer;
        string filename = "savegame.sav";

        SaveGameData saveGameData = new SaveGameData()
        {
            PlayerName = "Grunt",
            AvatarPosition = new Vector2(10, 15),
            Level = 3,
            Score = 99424,
            GameObjects = new List<BaseGameObject>() 
            { 
                new Soldier { Health = 10.0f, Position = new Vector3(0.0f, 10.0f, 0.0f) },
                new Grenade { TimeToDetonate = 3.0f, Position = new Vector3(4.0f, 3.0f, 0.0f) }
            }
        };

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

#if XBOX
            Components.Add(new GamerServicesComponent(this));
#endif

            currentKeyboardState = Keyboard.GetState();
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            oldKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            UpdateSaveKey(Keys.F1);
            UpdateSaving();

            base.Update(gameTime);
        }

        private void UpdateSaveKey(Keys saveKey)
        {
            if (!oldKeyboardState.IsKeyDown(saveKey) && currentKeyboardState.IsKeyDown(saveKey))
            {
                if (savingState == SavingState.NotSaving)
                {
                    savingState = SavingState.ReadyToOpenStorageContainer;
                }
            }
        }

        private void UpdateSaving()
        {
            switch (savingState)
            {
                case SavingState.ReadyToSelectStorageDevice:
#if XBOX
                    if (!Guide.IsVisible)
#endif
                    {
                        asyncResult = StorageDevice.BeginShowSelector(playerIndex, null, null);
                        savingState = SavingState.SelectingStorageDevice;
                    }
                    break;

                case SavingState.SelectingStorageDevice:
                    if (asyncResult.IsCompleted)
                    {
                        storageDevice = StorageDevice.EndShowSelector(asyncResult);
                        savingState = SavingState.ReadyToOpenStorageContainer;
                    }
                    break;

                case SavingState.ReadyToOpenStorageContainer:
                    if (storageDevice == null || !storageDevice.IsConnected)
                    {
                        savingState = SavingState.ReadyToSelectStorageDevice;
                    }
                    else
                    {
                        asyncResult = storageDevice.BeginOpenContainer("Game1StorageContainer", null, null);
                        savingState = SavingState.OpeningStorageContainer;
                    }
                    break;

                case SavingState.OpeningStorageContainer:
                    if (asyncResult.IsCompleted)
                    {
                        storageContainer = storageDevice.EndOpenContainer(asyncResult);
                        savingState = SavingState.ReadyToSave;
                    }
                    break;

                case SavingState.ReadyToSave:
                    if (storageContainer == null)
                    {
                        savingState = SavingState.ReadyToOpenStorageContainer;
                    }
                    else
                    {
                        try
                        {
                            DeleteExisting();
                            Save();
                        }
                        catch (IOException e)
                        {
                            // Replace with in game dialog notifying user of error
                            Debug.WriteLine(e.Message);
                        }
                        finally
                        {
                            storageContainer.Dispose();
                            storageContainer = null;
                            savingState = SavingState.NotSaving;
                        }
                    }
                    break;
            }
        }

        private void DeleteExisting()
        {
            if (storageContainer.FileExists(filename))
            {
                storageContainer.DeleteFile(filename);
            }
        }

        private void Save()
        {
            using (Stream stream = storageContainer.CreateFile(filename))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
                serializer.Serialize(stream, saveGameData);
            }
        }

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

            base.Draw(gameTime);
        }
    }
}
like image 100
Empyrean Avatar answered Nov 08 '22 19:11

Empyrean