111
社区成员




这个作业属于哪个课程 | 软件工程24年秋季 |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
这个作业的目标 | 完成软件工程实践总结&个人技术总结,并完成相应博客 |
其他参考文献 | 《构建之法》、CSDN |
在游戏开发中,保存与读取功能是不可或缺的核心部分,能够让玩家在退出游戏后继续从上次进度进行游戏。
本文旨在技术层面详细说明保存与读取功能的实现细节与设计思路。
保存功能: 将玩家当前游戏的状态(例如任务状态、玩家属性、位置等)以文件的形式持久化。
读取功能: 从保存文件中加载玩家的进度并还原游戏状态。
[System.Serializable]
public class GameData
{
// 玩家数据
public PlayerData playerData;
// 当前任务
public List<TaskData> activeTasks;
// 已完成任务
public List<TaskData> completedTasks;
// 背包和物品数据
public List<ItemData> inventoryItems;
// 玩家属性存储类
[System.Serializable]
public class PlayerData
{
public float knowledge;
public float fitness;
public float charm;
}
// 任务数据存储类
[System.Serializable]
public class TaskData
{
public int taskId;
public string taskName;
public string taskdescription;
public bool isCompleted;
public int requiredKnowledge;
public int requiredFitness;
public int requiredCharm;
}
// 物品数据存储类
[System.Serializable]
public class ItemData
{
public string itemName;
public int itemID;
public int itemHeld;
}
}
在运行时生成保存文件的路径,确保可以跨平台使用:
saveFilePath = Application.persistentDataPath + "/savefile.json";
保存功能负责将当前游戏状态序列化为 JSON 格式,并写入文件:
public void SaveGame()
{
SaveData data = new SaveData();
foreach (var task in completedTasks)
{
Debug.Log("Completed Task: " + task.taskName + " | IsCompleted: " + task.isCompleted);
}
// 保存玩家属性
data.charm = CharacterStats.Instance.GetCharm();
data.knowledge = CharacterStats.Instance.GetKnowledge();
data.fitness =CharacterStats.Instance.GetFitness();
// 保存任务状态
data.activeTaskIDs = new List<int>();
foreach (TaskSO task in activeTasks)
{
data.activeTaskIDs.Add(task.taskID);
Debug.Log(task.taskName + " Get");
}
data.completedTaskIDs = new List<int>();
foreach (TaskSO task in completedTasks)
{
data.completedTaskIDs.Add(task.taskID);
Debug.Log(task.taskName + " completed");
}
// 保存背包物品
data.inventoryItems = new List<ItemData>();
foreach (Item item in inventory.itemList)
{
ItemData itemData = new ItemData
{
itemName = item.itemName,
itemID = item.itemID,
itemHeld = item.itemHeld
};
data.inventoryItems.Add(itemData);
}
// 转换为JSON并写入文件
string json = JsonUtility.ToJson(data, true);
File.WriteAllText(saveFilePath, json);
Debug.Log("游戏已保存");
}
读取功能负责从保存文件中反序列化数据并恢复游戏状态:
public void LoadGame()
{
if (File.Exists(saveFilePath))
{
string json = File.ReadAllText(saveFilePath);
SaveData data = JsonUtility.FromJson<SaveData>(json);
// 加载玩家属性
CharacterStats.SetCharm(data.charm);
CharacterStats.SetKnowledge(data.knowledge);
CharacterStats.SetFitness(data.fitness);
// 加载任务状态
activeTasks.Clear();
completedTasks.Clear();
foreach (int taskID in data.activeTaskIDs)
{
TaskSO task = FindTaskByID(taskID);
if (task != null)
{
activeTasks.Add(task);
// 根据任务类型分配到 mainTasks 或 sideTasks
if (task.isMainTask)
{
taskManager.mainTasks.Add(task);
}
else
{
taskManager.sideTasks.Add(task);
}
task.isCompleted = false;
Debug.Log("任务加载到 activeTasks: " + task.taskName);
}
else
{
Debug.LogWarning("未能加载任务ID: " + taskID);
}
}
foreach (int taskID in data.completedTaskIDs)
{
TaskSO task = FindTaskByID(taskID);
if (task != null)
{
completedTasks.Add(task);
task.isCompleted = true;
Debug.Log("任务加载到 completedTasks: " + task.taskName);
}
else
{
Debug.LogWarning("未能加载任务ID: " + taskID);
}
}
// 加载背包物品
inventory.itemList.Clear();
foreach (ItemData itemData in data.inventoryItems)
{
Item item = FindItemByID(itemData.itemID);
if (item != null)
{
item.itemHeld = itemData.itemHeld;
inventory.itemList.Add(item);
}
}
// 显示主线任务
taskManager.DisplayTasks(taskManager.mainTasks);
// 显示主线任务
taskManager.DisplayTasks(taskManager.sideTasks);
// 显示主线任务
taskManager.DisplayTasks(taskManager.completedTasks);
taskManager.RefreshTaskLists();
}
else
{
Debug.Log("未找到保存文件");
}
}
private TaskSO FindTaskByID(int id)
{
TaskSO[] allTasks = Resources.FindObjectsOfTypeAll<TaskSO>();
foreach (TaskSO task in allTasks)
{
if (task.taskID == id)
{
Debug.Log("找到任务: " + task.taskName + " (ID: " + task.taskID + ")");
return task;
}
}
Debug.LogWarning("未找到任务ID: " + id);
return null;
}
private Item FindItemByID(int id)
{
foreach (Item item in inventory.itemList)
{
if (item.itemID == id)
{
return item;
}
}
return null;
}
原因:
文件写入失败或保存路径无效。
解决方案:
检查文件路径是否有效,确保具有写权限。
原因:
游戏状态的还原逻辑与保存数据不匹配。
解决方案:
确保保存和读取逻辑一致性,调试具体字段。
通过上述技术设计,游戏的保存与读取功能可以高效、稳定地实现,并支持未来的功能扩展。玩家能够体验无缝的游戏进度保存与加载,提升游戏体验。