Implemented Save and Load functionality

pull/52/head
Katharina Ziolkowski 2 months ago
parent b65a3bbd6d
commit ba7d550c3f

@ -317,6 +317,11 @@ DebugEntities={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"location":0,"echo":false,"script":null)
] ]
} }
SaveGame={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194336,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[internationalization] [internationalization]

@ -14,13 +14,13 @@ public class Entity
id = new Random().NextInt64(); id = new Random().NextInt64();
} }
protected virtual void SaveEntity(JObject json) public virtual void SaveEntity(JObject json)
{ {
json["id"] = id; json["id"] = id;
json["type"] = EntityType; json["type"] = EntityType;
} }
protected virtual void LoadEntity(JObject json) public virtual void LoadEntity(JObject json)
{ {
id = json.GetLongValue("id"); id = json.GetLongValue("id");
} }

@ -1,13 +1,32 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using Newtonsoft.Json.Linq;
namespace Babushka.scripts.CSharp.GameEntity.Entities; namespace Babushka.scripts.CSharp.GameEntity.Entities;
public class LoadedScenesEntity : Entity public class LoadedScenesEntity : Entity
{ {
private HashSet<string> _loadedScenes = new(); private HashSet<string> _loadedScenes = new();
public override string EntityType => "LoadedScenesEntity"; public override string EntityType => OWN_TYPE_NAME;
public const string OWN_TYPE_NAME = "LoadedScenesEntity";
public void AddScene(string sceneName) => _loadedScenes.Add(sceneName); public void AddScene(string sceneName) => _loadedScenes.Add(sceneName);
public bool WasSceneLoaded(string sceneName) => _loadedScenes.Contains(sceneName); public bool WasSceneLoaded(string sceneName) => _loadedScenes.Contains(sceneName);
public override void SaveEntity(JObject json)
{
base.SaveEntity(json);
json["scenes"] = new JArray(_loadedScenes);
}
public override void LoadEntity(JObject json)
{
base.LoadEntity(json);
JArray array = (JArray?) json["scenes"] ?? throw new Exception("No scenes found in LoadedScenesEntity.");
_loadedScenes = array.ToObject<HashSet<string>>()!;
}
} }

@ -6,22 +6,21 @@ namespace Babushka.scripts.CSharp.GameEntity.Entities;
public abstract class PositionalEntity : Entity public abstract class PositionalEntity : Entity
{ {
private Node2D _positionalNodeRef;
public Vector2 position; public Vector2 position;
public string sceneName = "none"; public string sceneName = "none";
protected override void SaveEntity(JObject json) public override void SaveEntity(JObject json)
{ {
base.SaveEntity(json); base.SaveEntity(json);
json["posx"] = _positionalNodeRef.Position.X; json["posx"] = position.X;
json["posy"] = _positionalNodeRef.Position.Y; json["posy"] = position.Y;
json["scene"] = sceneName; json["scene"] = sceneName;
} }
protected override void LoadEntity(JObject json) public override void LoadEntity(JObject json)
{ {
base.LoadEntity(json); base.LoadEntity(json);
_positionalNodeRef.Position = new Vector2( position = new Vector2(
json.GetFloatValue("posx"), json.GetFloatValue("posx"),
json.GetFloatValue("posy")); json.GetFloatValue("posy"));
sceneName = json.GetStringValue("scene"); sceneName = json.GetStringValue("scene");

@ -8,7 +8,7 @@ public static class EntityLoadSaveUtil
{ {
var token = json[key]; var token = json[key];
if (token == null) throw new MalformedJsonException(json, key, "does not exist"); if (token == null) throw new MalformedJsonException(json, key, "does not exist");
if (!token.HasValues) throw new MalformedJsonException(json, key, "has no value"); //if (!token.HasValues) throw new MalformedJsonException(json, key, "has no value");
if (token.Type != type) throw new MalformedJsonException(json, key, $"is not of type {type}"); if (token.Type != type) throw new MalformedJsonException(json, key, $"is not of type {type}");
} }

@ -1,6 +1,9 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Babushka.scripts.CSharp.GameEntity.Entities;
using Godot; using Godot;
using Newtonsoft.Json.Linq;
using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity; using Entity = Babushka.scripts.CSharp.GameEntity.Entities.Entity;
using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity; using PositionalEntity = Babushka.scripts.CSharp.GameEntity.Entities.PositionalEntity;
@ -15,6 +18,7 @@ public partial class EntityManager : Node
public static EntityManager Instance; public static EntityManager Instance;
[Export] private EntityNodeCreator _nodeCreator = null!; [Export] private EntityNodeCreator _nodeCreator = null!;
[Export] private string saveDirectory = "user://save_data/";
private EntitySceneContainer? _currentEntitySceneContainer; private EntitySceneContainer? _currentEntitySceneContainer;
private readonly List<Entity> _allEntities = new(); private readonly List<Entity> _allEntities = new();
@ -27,6 +31,7 @@ public partial class EntityManager : Node
public override void _EnterTree() public override void _EnterTree()
{ {
Instance = this; Instance = this;
Load();
} }
public override void _Input(InputEvent @event) public override void _Input(InputEvent @event)
@ -40,6 +45,58 @@ public partial class EntityManager : Node
GD.Print(entity.EntityType + " " + entity.id); GD.Print(entity.EntityType + " " + entity.id);
} }
} }
if(@event.IsActionPressed("SaveGame")) Save();
}
public void Save()
{
JArray array = new JArray();
foreach (var entity in AllEntities)
{
JObject saveData = new JObject();
entity.SaveEntity(saveData);
array.Add(saveData);
}
using var SaveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Write);
SaveFile.StoreString(array.ToString());
}
public void Load()
{
using var saveFile = FileAccess.Open(saveDirectory + "save.json", FileAccess.ModeFlags.Read);
if (saveFile == null) return;
JArray array = JArray.Parse(saveFile.GetAsText());
foreach (var token in array)
{
var jobj = (JObject)token;
if (jobj == null) continue;
if (jobj.TryGetValue("type", out var entityType))
{
string entityTypeString = (string) entityType!;
Entity entity = InitializeEntity(entityTypeString);
entity.LoadEntity(jobj);
AddEntity(entity);
}
}
}
private Entity InitializeEntity(string type)
{
Entity entity = type switch
{
TrashEntity.OWN_TYPE_NAME => new TrashEntity(),
LoadedScenesEntity.OWN_TYPE_NAME => new LoadedScenesEntity(),
_ => throw new Exception($"Trying to load unknown entity type: {type}")
};
return entity;
} }
#region ENTITY MANAGEMENT #region ENTITY MANAGEMENT

@ -16,14 +16,20 @@ public partial class EntitySceneContainer : Node2D
public override void _ExitTree() public override void _ExitTree()
{ {
EntityManager.Instance.Save();
EntityManager.Instance.UnsetSceneContainer(); EntityManager.Instance.UnsetSceneContainer();
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
loadedScenesEntity.AddScene(sceneName);
} }
public override void _Ready() public override void _Ready()
{ {
AddAllEntities(); AddAllEntities();
CallDeferred(nameof(RegisterWithScenesEntity));
}
private void RegisterWithScenesEntity()
{
var loadedScenesEntity = EntityManager.Instance.GetUniqueEntity<LoadedScenesEntity>();
loadedScenesEntity.AddScene(sceneName);
} }
public void AddAllEntities() public void AddAllEntities()

Loading…
Cancel
Save