Android: отображение счета в виде строки на холсте создает новую строку для каждой команды рисования. Как мне обойти это? - PullRequest
0 голосов
/ 10 июня 2011

Я создаю игру, которая отображает некоторые числа на холсте (счет, время и т. Д.).

В настоящее время я делаю это с помощью команды drawtext на холсте

// score is some int
draw(Canvas c) {
    c.drawText(score+"", x, y, paintSyle);
}

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

Сейчас моя игра со всеми растровыми рисунками и всеми остальнымиОт 25 до 60 кадров в секунду.Мне бы хотелось, чтобы оно оставалось ближе к большему числу, и я пытаюсь найти способы ускорить его.

Было бы быстрее / лучше создать (или найти?) Какой-то изменчивый подкласс строки иобойти эту проблему?Есть ли другой способ решить эту проблему?Или это просто так?

Ответы [ 3 ]

1 голос
/ 16 февраля 2013

Мой друг сообщил мне решение этой проблемы. Если вы хотите со временем что-то нарисовать, один из лучших (и самых простых) механизмов для этого - разделить то, что вам нужно сделать, на два совершенно отдельных процесса.

т. Используйте команду draw только для рисования, сохраняйте логику / присваивание в Draw () на абсолютном минимуме.

private final long TIMER_PERIOD = 500;
private String timeString;
private Runnable updateRunnable;
private Handler updateHandler = new Handler();

public void onCreate(Bundle savedInstanceState) {
    updateRunnable = new Runnable() {
        @Override
        public void run() {
            timeString = GetTimeString();
            updateHandler.postDelayed(updateRunnable, TIMER_PERIOD);
        }
    }
}

Draw(Canvas c) {
    c.drawText(timeString, x, y, paintStyle);
}

В этом примере команда Draw просто берет timeString в ее текущем состоянии и выводит ее на экран. Это высокоэффективное использование функции рисования, поскольку она не требует создания объектов, и нет никакой логики, которая не требуется немедленно для любого рисования. , В фоновом режиме Runnable выполняет функцию run () каждые 500 миллисекунд (приблизительно). Просто обновите функцию Run (), используя любую логику, необходимую для вычисления времени (в примере есть фиктивная функция GetTimeString())

Надеюсь, это полезно.

1 голос
/ 11 ноября 2013

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

Где-то в начале вашей игры (onCreate, onResume, как часть синглтона при запуске приложения и т. д.) создайте большую строку [], которая может содержать максимумсчет (моя игра заполняет массив 10000, поэтому максимальный счет будет 9999).Затем зациклите его с помощью цикла for, заполняя каждый индекс String.valueOf (i).

for (int i = 0; i <scoreStrings.length; i++)
        {
            scoreStrings[i] = String.valueOf(i);
        }

Теперь, когда вам нужно нарисовать счет, просто используйте int, который вы используете, чтобы сохранить счетв качестве индекса для этого массива и «эй, presto!», вы получите правильную строку для вашего счета.

canvas.drawText(scoreStrings[score], x, y, paint);
1 голос
/ 10 июня 2011

Введите две новые private переменные-члены String renderedScoreString и int rederedScore и перепишите ваш draw() -метод так:

draw(Canvas c) {
    if (this.score != this.renderedScore || this.renderedScoreString == null) {
        this.renderedScore = this.score;
        this.renderedScoreString = Integer.toString(this.renderedScore);
    }
    c.drawText(this.renderedScore, x, y, paintStyle);
}

, который должен вас спасти!создания объектов.Вы также можете скрыть шаблон кода за методом получения, например, String getScoreString(), который делает то же самое, поэтому у вас его нет в методе draw().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...