Merge branch 'world-loading-scene' into main
Add a loading screen (WorldLoadingScene) between world setup/load and WorldScene so the blocking world generation shows a "Generating world" indicator instead of a blank fade. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -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