Loading screen between world setup and the game scene
World generation (WorldScene.OnLoad: terrain, atlases, spawn) runs synchronously and blocks the frame; previously only a blank fade covered it, with no feedback. New WorldLoadingScene shows a "Generating world" label, lets it draw, then switches to WorldScene WITHOUT a transition so its last drawn frame (the label) stays on screen during the blocking generation. Both New World and Load Game route through it. Localized loading.world ru/en. Build + --check-content clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
282ec018f7
commit
6ec70cab91
@@ -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",
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
"menu.settings": "Настройки",
|
||||
"menu.credits": "Авторы",
|
||||
"menu.quit": "Выход",
|
||||
"loading.world": "Создание мира",
|
||||
"newworld.title": "Новый мир",
|
||||
"newworld.name": "Название",
|
||||
"newworld.defaultname": "Новый мир",
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Экран загрузки между окном создания/выбора мира и игровой сценой. Генерация мира
|
||||
/// (<see cref="WorldScene.OnLoad"/>: рельеф, атласы, спавн) идёт синхронно и блокирует кадр; раньше под
|
||||
/// ней был лишь сплошной фейд без индикатора. Эта сцена рисует надпись «Создание мира…», даёт ей
|
||||
/// прорисоваться, затем переключается на <see cref="WorldScene"/> БЕЗ перехода — её последний кадр
|
||||
/// (надпись) и остаётся на экране, пока идёт генерация, давая игроку понятную обратную связь.
|
||||
/// </summary>
|
||||
public sealed class WorldLoadingScene : Scene
|
||||
{
|
||||
private readonly WorldConfig _config;
|
||||
private readonly WorldSave? _save;
|
||||
private GameSettings _settings = new();
|
||||
private Label _label = null!;
|
||||
private int _frames;
|
||||
|
||||
/// <summary>Новый мир (<paramref name="save"/> = null) или загрузка сохранения.</summary>
|
||||
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<GameContent>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user