diff --git a/Mods/Core/Languages/en/ui.json b/Mods/Core/Languages/en/ui.json index 1a7272b..a6fc144 100644 --- a/Mods/Core/Languages/en/ui.json +++ b/Mods/Core/Languages/en/ui.json @@ -92,6 +92,7 @@ "menu.settings": "Settings", "menu.credits": "Credits", "menu.quit": "Quit", + "loading.world": "Generating world", "newworld.title": "New World", "newworld.name": "Name", "newworld.defaultname": "New World", diff --git a/Mods/Core/Languages/ru/ui.json b/Mods/Core/Languages/ru/ui.json index 8550b50..ad384f2 100644 --- a/Mods/Core/Languages/ru/ui.json +++ b/Mods/Core/Languages/ru/ui.json @@ -92,6 +92,7 @@ "menu.settings": "Настройки", "menu.credits": "Авторы", "menu.quit": "Выход", + "loading.world": "Создание мира", "newworld.title": "Новый мир", "newworld.name": "Название", "newworld.defaultname": "Новый мир", diff --git a/src/LittleSim/Scenes/LoadGameScene.cs b/src/LittleSim/Scenes/LoadGameScene.cs index 586a466..6437a13 100644 --- a/src/LittleSim/Scenes/LoadGameScene.cs +++ b/src/LittleSim/Scenes/LoadGameScene.cs @@ -73,7 +73,7 @@ public sealed class LoadGameScene : Scene if (!Context.Scenes.IsTransitioning) { Context.Scenes.Switch( - new WorldScene(save.ToConfig(), save), + new WorldLoadingScene(save.ToConfig(), save), Transitions.Fade(0.6f) ); } diff --git a/src/LittleSim/Scenes/NewWorldScene.cs b/src/LittleSim/Scenes/NewWorldScene.cs index abcfa4a..c9c3f96 100644 --- a/src/LittleSim/Scenes/NewWorldScene.cs +++ b/src/LittleSim/Scenes/NewWorldScene.cs @@ -154,7 +154,7 @@ public sealed class NewWorldScene : Scene Seed = seed, SmoothPasses = _smoothing, }; - Context.Scenes.Switch(new WorldScene(config), Transitions.Fade(0.6f)); + Context.Scenes.Switch(new WorldLoadingScene(config), Transitions.Fade(0.6f)); } private void Back() diff --git a/src/LittleSim/Scenes/WorldLoadingScene.cs b/src/LittleSim/Scenes/WorldLoadingScene.cs new file mode 100644 index 0000000..44771f6 --- /dev/null +++ b/src/LittleSim/Scenes/WorldLoadingScene.cs @@ -0,0 +1,63 @@ +using LittleSim.App; +using LittleSim.Content; +using LittleSim.UI; +using MrGameEng.Core; +using MrGameEng.UI; +using Myra.Graphics2D.UI; + +namespace LittleSim.Scenes; + +/// +/// Экран загрузки между окном создания/выбора мира и игровой сценой. Генерация мира +/// (: рельеф, атласы, спавн) идёт синхронно и блокирует кадр; раньше под +/// ней был лишь сплошной фейд без индикатора. Эта сцена рисует надпись «Создание мира…», даёт ей +/// прорисоваться, затем переключается на БЕЗ перехода — её последний кадр +/// (надпись) и остаётся на экране, пока идёт генерация, давая игроку понятную обратную связь. +/// +public sealed class WorldLoadingScene : Scene +{ + private readonly WorldConfig _config; + private readonly WorldSave? _save; + private GameSettings _settings = new(); + private Label _label = null!; + private int _frames; + + /// Новый мир ( = null) или загрузка сохранения. + public WorldLoadingScene(WorldConfig config, WorldSave? save = null) + { + _config = config; + _save = save; + } + + protected override void OnLoad() + { + _settings = GameSettingsStore.Load(); + var desktop = this.UseScaledUI(); // ставит MyraEnvironment.Game до создания виджетов + _label = new Label + { + TextColor = Ui.Accent, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + }; + desktop.Root = Ui.Screen(_label); + UpdateSystems.Add(new CallbackSystem(Tick)); + } + + private void Tick() + { + var content = Context.Services.Get(); + var word = content.Languages.Get("loading.world"); + var dots = new string('.', (int)(Context.Clock.UnscaledTotalTime * 2) % 4); + _label.Text = word + dots; + + // Дождаться, пока надпись точно прорисована (переход въезда завершён + пара кадров), затем + // мгновенно переключиться: блокирующий WorldScene.OnLoad оставит на экране кадр с надписью. + _frames++; + if (Context.Scenes.IsTransitioning || _frames < 2) + { + return; + } + + Context.Scenes.Switch(new WorldScene(_config, _save)); + } +}