在某个时候保存对象变量,并在保存时完全重用它们吗?

时间:2018-06-22 12:31:36

标签: c#

假设我有一个类型为Player的对象,该对象具有健康状况,位置和颜色变量。

游戏经历了几个阶段,所有变量在此阶段都会发生变化。例如:

  • Stage1播放器具有80的生命值,50.3f位置和绿色。

  • Stage2播放器具有50点生命值,90f位置和蓝色。

在阶段3中,我想选择完全相同的Stage1或Stage2变量副本(随机)。

我可以执行此操作的一种方法是,在每个阶段中,将这些变量分配给另一个Player对象,例如

CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
if (res != 0) {
    fprintf("Failed global init ...\n");
    exit(1);
}
CURL *curl = curl_easy_init();
if (!curl) {
    ///
}

// Etc.

curl_easy_cleanup(curl);
curl_global_cleanup();

与我对Stage2所做的相同,然后在Stage3中重用这些对象之一。但是,如果我要保存很多变量该怎么办?例如,除了这3个变量外,我还有20、30个以上的变量。保存每个变量的过程很丑。

是否还有其他(更简便的)方法来保存然后重用某些阶段所需的变量?例如,在确切的阶段保存对象的副本,然后在需要时稍后重用其变量?

2 个答案:

答案 0 :(得分:1)

要复制对象,可以使用copy constructor的概念,也可以使用Cloning

但是正如您所提到的,播放器的数量可能会增加,我建议您仅存储那些将在各个阶段更改的信息(不保存不会更改信息的信息)

您的代码应该看起来与此类似

假设您有Player类,那么您也应该也有PlayerInfo类,例如

public class Player
{
public int PId;     //This will not change
public string Name; //This will not change
public int Energy;  //This may change over stanges

//you should have a method which returns PlayerInfo object
public PlayerInfo GetPlayerInfoToBeStored()
{
    return new PlayerInfo(this.Energy);
}
}

//this class will have only those information which can change
public class PlayerInfo
{
public int Energy;

public PlayerInfo(int playerEnergey)
{
    Energy = playerEnergey;
}
}

虽然实际使用可以是这样,

您可以拥有一个愉快的字典

public Dictionary<int, Dictionary<int, PlayerInfo>> StoredPlayerState = 
    new Dictionary<int, Dictionary<int, PlayerInfo>>();

以及在其中添加信息的方法。

public void SavePlayerInfo(int stageNum, List<Player> playerList)
{
    Dictionary<int, PlayerInfo> playerInfoTable = new Dictionary<int, PlayerInfo>();
    foreach(Player player in playerList)
    {
        playerInfoTable.Add( player.PId, player.GetPlayerInfoToBeStored());
        StoredPlayerState.Add(stageNum, playerInfoTable);
    }
}

和一种将当前播放器设置为先前设置值的方法

public void ResetPlayerWithOldValues(int stageNum, List<Player> originalPlayerList)
{
    if (StoredPlayerState.ContainsKey(stageNum))
    {
        foreach(Player originalPlayer in originalPlayerList)
        {
            if (StoredPlayerState[stageNum].ContainsKey(originalPlayer.PId))
            {
                PlayerInfo playerInfo = StoredPlayerState[stageNum][originalPlayer.PId];
                originalPlayer.Energy = playerInfo.Energy;
            }
        }
    }
}

现在使用此流程非常简单,

public void MainMethod()
{
    List<Player> playerList = new List<Player>();
    //add players in this list

    //after stage 1
    SavePlayerInfo(1, playerList);

    //after stage 2
    SavePlayerInfo(2, playerList);

    //At stage 3 :setting current players with any of those two state's values
    ResetPlayerWithOldValues(randomStageNum, playerList);

    //and simply keep using playerList
}

答案 1 :(得分:1)

在开发游戏时,通常会创建一个单例来存储要保留或在不同场景中更新的全局游戏变量。如果我对您的理解正确,那么这可能会对您有所帮助:

public class PlayerState
{
    public int PlayerHealth { get; set; }
    public float PlayerPosition { get; set; }
}

这是单身人士:

public sealed class GameVariables 
{
    private static readonly _instance = new GameVariables();

    public static GameVariables Intance { get { return _instance; } }

    private GameVariables()
    {
        Reset();
    }

    public void Reset()
    {
       //Initialize your variables here when you start a new game
       TotalScore = 0;

       PlayerStates = new Dictionary<int, PlayerState>();
       [...]
    }

    public Dictionary<int, PlayerState> PlayerStates { get; private set; }
    public int TotalScore { get; set; }
    [...]
}

然后在游戏过程中,只需初始化玩家状态并在需要时获取实例:

public class Scene3
{
    void Start()
    {
        GameVariables.Instance.PlayerStates.Add(3, new PlayerState());
    }

    void Update() 
    {
        //Get player state for scene 1
        PlayerState playerStateScene1 = GameVariables.Instance.PlayerStates[1];

        //Get player state for scene 2
        PlayerState playerStateScene2 = GameVariables.Instance.PlayerStates[2];

        //Update player state for this scene
        GameVariables.Instance.PlayerStates[3].PlayerHealth = 80;
        GameVariables.Instance.PlayerStates[3].TotalScore += 100;
        [...]
    }
}

如果您从主菜单重新开始,别忘了重置游戏:

public class MainMenu
{
     void Play()
     {
         GameVariables.Instance.Reset();
     }
}