reckfellENGINE

Пауза: игровой мир, интерфейс и таймеры

ProcessMode, физика, сигналы и CreateTimer; рабочие кнопки паузы и продолжения.

На этой странице

Запустить паузу с работающим интерфейсом

Добавьте ProcessCounter2D.cs и PauseDemo2D.cs в C#-проект 1.0.0. Прикрепите PauseDemo2D к Entity2D отдельного уровня, задайте viewport 640×420, соберите и нажмите F6. Pausable останавливается после кнопки «Пауза», Always и статус продолжают обновляться. «Продолжить» возвращает игровое время.

Игровой счётчик остановлен, интерфейс продолжает работать при Paused = true

ProcessCounter2D.cs
C#
using Reckfell;

public partial class ProcessCounter2D : Entity2D
{
    public double Elapsed { get; private set; }
    public int ProcessCalls { get; private set; }
    public int PhysicsCalls { get; private set; }

    public override void _Process(double delta) { Elapsed += delta; ProcessCalls++; QueueRedraw(); }
    public override void _PhysicsProcess(double delta) => PhysicsCalls++;
    public override void _Draw()
    {
        DrawCircle(Vector2.Zero, 36, new Color(.08f, .09f, .11f));
        DrawCircle(Vector2.FromAngle((float)Elapsed * 2) * 27, 8, new Color(.25f, .45f, 1));
        DrawString(ThemeDB.FallbackFont, new Vector2(-40, 64), Name.ToString(), fontSize: 17);
    }
}
PauseDemo2D.cs
C#
using Reckfell;

public partial class PauseDemo2D : Entity2D
{
    public ProcessCounter2D GameClock { get; private set; } = null!;
    public ProcessCounter2D UiClock { get; private set; } = null!;
    public Label Status { get; private set; } = null!;
    private bool _previousPause;

    public override void _EnterTree()
    {
        ProcessMode = ProcessModeEnum.Always;
        _previousPause = GetTree().Paused;
    }

    public override void _Ready()
    {
        bool ru = TranslationServer.GetLocale().StartsWith("ru");
        AddChild(new Label { Position = new Vector2(28, 24), Text = ru ? "Пауза: игровое время и интерфейс" : "Pause: game time and interface" });
        GameClock = new ProcessCounter2D { Name = "Pausable", Position = new Vector2(180, 225), ProcessMode = ProcessModeEnum.Pausable };
        UiClock = new ProcessCounter2D { Name = "Always", Position = new Vector2(440, 225), ProcessMode = ProcessModeEnum.Always };
        AddChild(GameClock);
        AddChild(UiClock);
        Status = new Label { Position = new Vector2(28, 340) };
        AddChild(Status);
        var pause = new Button { Position = new Vector2(28, 82), Text = ru ? "Пауза" : "Pause" };
        var resume = new Button { Position = new Vector2(160, 82), Text = ru ? "Продолжить" : "Resume" };
        pause.Pressed += () => GetTree().Paused = true;
        resume.Pressed += () => GetTree().Paused = false;
        AddChild(pause);
        AddChild(resume);
    }

    public override void _Process(double delta)
    {
        if (Status is not null) Status.Text = "Paused: " + GetTree().Paused + " | Pausable: " + GameClock.ProcessCalls + " | Always: " + UiClock.ProcessCalls;
    }

    public override void _ExitTree() => GetTree().Paused = _previousPause;
}

Демонстрация владеет глобальной паузой и при выходе восстанавливает исходное состояние. В игре назначьте одного ответственного контроллера; несколько независимых компонентов, меняющих один Paused, могут снять чужую паузу.

Выбрать ProcessMode

Режим EntityПоведение
InheritНаследует режим по иерархии Parent
PausableОбрабатывается, когда EntityTree.Paused = false
WhenPausedОбрабатывается, когда Paused = true
AlwaysОбрабатывается при обоих состояниях
DisabledОбычная обработка отключена; дети с собственным явным режимом могут отличаться

Наследование режима следует Parent, а не сериализационному Owner. IsProcessing показывает включённый callback, но не обещает, что объект сейчас проходит паузу и условия активного дерева. Для этого есть CanProcess. SetProcess(false) и ProcessMode решают связанные, но разные задачи.

Контроллер кнопки продолжения должен обрабатываться при паузе: оставленный Pausable интерфейс может потерять ввод, которым вы собирались его оживить. Сигналы и прямые методы, включая CallGroup, не перестают выполняться только из-за Paused. Сам факт, что обработчик перестал получать _Process, не делает его недоступным для других вызовов.

Физика и ожидания

EntityTree.Paused останавливает 2D/3D physics servers в обычном режиме. Always может продолжать _PhysicsProcess callback, но сам по себе не включает остановленную симуляцию. Стенд проверяет одновременно растущий счётчик Always и остановленное RigidBody2D. Не путайте выполнение кода физического шага с интеграцией тела.

ОжиданиеПоведение при паузе
CreateTimer(seconds)По умолчанию processAlways = true: таймер продолжает идти
CreateTimer(seconds, processAlways: false)Останавливается до продолжения игры
Entity TimerУчитывает свой ProcessMode и отдельные свойства Timer
Подписка/await на сигналМожет завершиться, если источник испустит сигнал во время паузы

Пауза не равна Engine.TimeScale = 0 и не равна удалению объекта. Для замедления, игнорирования time scale и физического шага таймера нужны отдельные настройки. Проверены обе политики EntityTreeTimer, Timer с Pausable/Always, сигналы и возобновление; системный сон приложения и все платформенные события этим примером не покрыты.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.