PlayerSaveData를 클래스로 만들어, 저장할 데이터를 그대로 멤버 변수로 선언해주었다.
[Serializable]
public class PlayerSaveData
{
public string Name;
public JobType Job;
public Stats Stats;
public List<Item> InventoryItems;
}
그런 후 SavePlayer()를 통해 JSON으로 직렬화 후 저장하는 메서드를 구현했다.
public static void SavePlayer(Player player, Action onCompleted)
{
// 플레이어의 데이터 PlayerSaveData로 저장
PlayerSaveData data = new PlayerSaveData
{
Name = player.Name,
Job = player.GetJobType(),
Stats = player.stats,
InventoryItems = player.inven.Items.ToList()
};
// JSON 형식으로 직렬화 후 파일에 저장
string json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(PLAYER_SAVEDATA, json);
// 완료 콜백 호출
onCompleted?.Invoke();
}
⛔ 하지만 여기서 문제가 발생했다.
PlayerData.json 파일이 생기긴 했지만 안에 내용이 없는 것이었다.
그런데 비슷한 방식으로 아이템 저장도 구현을 했었는데 아이템은 또 저장이 잘되었다.
public struct ItemSaveData // 아이템 저장 데이터 구조체
{
// 아이템의 정보들
public string Name { get; set; }
public ItemType Type { get; set; }
public int Value { get; set; }
public string Info { get; set; }
public int Cost { get; set; }
public bool IsOwn { get; set; }
public bool IsEquip { get; set; }
public ItemSaveData(string name, ItemType type, int value, string info, int cost, bool isOwn, bool isEquip)
{
Name = name;
Type = type;
Value = value;
Info = info;
Cost = cost;
IsOwn = isOwn;
IsEquip = isEquip;
}
}
ItemSaveData는 구조체로 만들어 저장하고
// Item SaveData로 저장
public ItemSaveData ToSaveData()
{
// 각 아이템 정보들 ItemSaveData에 저장하여 반환
return new ItemSaveData(
itemStat.Name,
Type,
itemStat.Value,
itemStat.Info,
itemStat.Cost,
IsOwn,
IsEquip
);
}
Item 내부 변수들이 다 외부에서 접근이 불가능하도록 해놓아서 클래스 내부에서 데이터를 저장해서 넘기도록 하였다.
아무튼 이 아이는 잘 저장이 되는데 왜 Player의 정보는 잘 안되는가 해서 찾아보니 저장하려는 정보에 private 접근자가 있으면 직렬화가 되지않는다는 정보를 알게되었다.
그래서 Stats 안에 있는 변수를 다 뽑아냈다.
public class PlayerSaveData
{
public string Name;
public JobType Job;
public int Level;
public int Hp;
public float Attack;
public int Defense;
public int ItemAttack;
public int ItemDefense;
public int Gold;
public int clearTime;
}
이렇게 정리하고 Player 클래스에도 Item과 같이 ToSaveData() 메서드를 구현했다.
// 플레이어의 정보들 PlayerSaveData로 변환
public PlayerSaveData ToSaveData()
{
PlayerSaveData data = new PlayerSaveData
{
Name = Name,
Job = jobType,
Level = stats.Level,
Hp = stats.Hp,
Attack = stats.Attack,
Defense = stats.Defense,
ItemAttack = stats.ItemAttack,
ItemDefense = stats.ItemDefense,
Gold = stats.Gold,
clearTime = clearTime,
};
// 저장된 데이터 반환
return data;
}
아니 그런데 이게 무슨 일인가 여전히 내용이 저장이 되지않는 것이었다.
그래서 ItemSaveData과 똑같이 구조체로 만들고 프로퍼티로 다 만들어주었다
[Serializable]
public struct PlayerSaveData
{
public string Name { get; set; }
public JobType Job { get; set; }
public int Level { get; set; }
public int Hp { get; set; }
public float Attack { get; set; }
public int Defense { get; set; }
public int ItemAttack { get; set; }
public int ItemDefense { get; set; }
public int Gold { get; set; }
public int clearTime { get; set; }
}
이렇게 하니 잘 저장이 되는 모습을 확인할 수 있었다. 😁
그래서 왜 그랬는지 여기저기 찾아보니,
- Json은 프로퍼티를 더 선호
- 값 타입이 참조 타입보다 직렬화가 안정적
이라는 내용을 찾아 볼 수 있었다.
이제 알게되었으니 앞으로는 데이터를 저장할 때 위 사항들을 유념해서 저장을 시도해야겠다 👌
그 이후로 불러오는 것은 어려울게 없으니,
JSON 파일 역직렬화해서 데이터로 가져오고, 그 값들을 다 적용시켜주었다.
추가로 데이터를 저장도 했으니 이제 게임 시작 시 새로하기 와 이어하기 화면도 만들어주었다.
public void StartGame()
{
while (true)
{
Console.Clear();
BannerManager.Show("SPARTA");
int choice = InputHandler.InputValidator("1. 새로하기\n2. 이어하기", 1, 2);
if (choice == 1) // 새로 하기
{
ItemManager.Instance.items = ItemManager.Instance.CreateItem();
CreatePlayer();
break;
}
else // 이어 하기
{
player = SaveData.LoadPlayer();
if (player != null)
{
// 저장된 아이템 로드
ItemManager.Instance.LoadItems(player);
Console.WriteLine("게임 시작!");
MainGame();
break;
}
}
}
}
// 저장하고 나가기
private void SaveAndQuit()
{
// 플레이어와 아이템 정보 저장
SaveData.SavePlayer(player, () => Console.WriteLine("\n플레이어 정보 저장 완료!"));
ItemManager.Instance.SaveItems(() => Console.WriteLine("\n아이템 데이터 저장 완료!"));
Console.WriteLine("\n게임이 종료됩니다...");
Thread.Sleep(1000);
}
저장 완료시 콜백 호출받아 Console에 출력되도록 하였다.
과제 제출 전에 급하게 부랴부랴 구현해서 코드도 지저분하고, 로컬에 저장되지만 암호화도 되지않아 데이터의 조작이 너무나도 쉬운게 흠이다.
TextRpg를 만들어보면서 문법과 많이 친해졌다고 느낀다.
이제 알고리즘 공부도하고 관련 코딩테스트 문제들도 많이 풀어보며
알고리즘들의 개념과 문제 해결능력을 길러 코딩테스트에서도 좋은 평가를 받을 수 있도록 노력할 것이다.