在 XNA 4.0 中保存游戏数据的好例子是什么? [英] What is a good example of saving game data in XNA 4.0?

查看:50
本文介绍了在 XNA 4.0 中保存游戏数据的好例子是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力阅读有关保存和读取游戏数据的 XNA MSDN 文档,但运气不佳.

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 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 then load them in the next time the game loads. Basically saving the state of the world.

推荐答案

如果您使用 XNA 4.0 帮助中所示的 XmlSerializer,则基类需要为它们可以使用的每个具体类型指定 [XmlInclude(Type)] 属性序列化成.

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.

以下是如何在 XNA 4.0 中保存游戏数据的示例.游戏运行后按F1保存.数据将保存到类似于 C:\Users\{username}\Documents\SavedGames\WindowsGame\Game1StorageContainer\Player1 的位置.

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.

要使其在 XBox 上运行,请添加对 Microsoft.Xna.Framework.GamerServices & 的引用.System.Xml.Serialization.

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);
        }
    }
}

这篇关于在 XNA 4.0 中保存游戏数据的好例子是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆