Как приостановить перерисовку в XNA? - программирование
Подтвердить что ты не робот

Как приостановить перерисовку в XNA?

Я сделал просмотрщик изображений XNA, но он всегда перерисовывает сцену, даже если она не меняется, и это заставляет мой нетбук сгореть, как ад, поэтому я хотел бы сделать паузу при рисовании, когда ничего не изменится.

Уменьшение частоты кадров до 1 - это один из способов сохранить ее в прохладном состоянии, но это приводит к задержке выхода.

Как предотвратить перерисовку, пока нет ввода?


Эта проблема была решена, но была обнаружена еще одна проблема - игра потребляет много CPU, когда ее окно находится в фокусе, но когда это не так, это занимает всего около 1% от CPU. См. Этот вопрос для получения подробной информации о том, как решить эту другую проблему:

Как уменьшить загрузку процессора XNA, в то время как ничего не стоит вычислять?

4b9b3361

Ответ 1

Вы можете использовать метод Game.SupressDraw для этой цели. Из замечаний по ссылке:

Вызовите этот метод во время обновления, чтобы предотвратить любые вызовы Draw, пока после следующего вызова Update. Этот метод можно использовать на небольших устройствах для экономии времени автономной работы, если дисплей не изменился в результате обновления. Например, если экран статичен без фоновой анимации, вход игрока может быть проверен во время обновления, чтобы определить, выполняет ли игрок какое-либо действие. Если вход не обнаружен, этот метод позволяет пропустить рисунок до следующего обновления.

В качестве примера следующий код будет вызывать только функцию Draw один раз. Когда я протестировал это, я заметил, что использование ЦП было высоким (70%) без вызова SuppressDraw. При использовании SupressDraw использование ЦП резко сократилось (до менее 15%). Ваши номера могут отличаться.

public class Game1 : Microsoft.Xna.Framework.Game
{
    ...
    private bool _drawn = false;
    protected override void Update(GameTime gameTime)
    {
        if (_drawn)
            SuppressDraw();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        /* draw stuff here */
        spriteBatch.End();

        _drawn = true;
    }
    ...
}

Обратите внимание, что SupressDraw только подавляет один вызов Draw. Чтобы предотвратить больше вызовов Draw, вы должны постоянно звонить SupressDraw в Update. Надеюсь, это имеет смысл.

Ответ 2

Как гласит принятый ответ, вы можете использовать SuppressDraw, чтобы избежать рисования неизмененного кадра. Однако ваш метод Update будет работать независимо от того, почему он все еще использует больше процессора, чем вы ожидаете. Чтобы избежать использования как можно большего количества CPU, вам нужно как-то избежать обновления вещей, которые, как вы знаете, не изменились с момента последнего кадра.

Я предполагаю, что вы знаете это так же, как вы знаете, когда подавлять дро, так что вам нужно переставить свой метод Update следующим образом:

private void Update(GameTime gameTime)
{
    var frameHasChanges = DetectChanges(); //This method you need to figure out yourself
    if (!frameHasChanges)
    {
        SuppressDraw();
        base.Update(gameTime);
        return;
    }

    //Do the rest of normal Update

}

В качестве окончательного замечания; Мне никогда не приходилось использовать это в любой игре, которую я когда-либо делал. Я считаю, что у вас может быть и другая, основная проблема с производительностью. Однако я использовал много методов, чтобы избежать рендеринга текста и т.д. На каждом кадре (вызывает бокс/распаковку). Спросите об этом в комментарии, если хотите узнать больше.