Кажется очевидным, что основной причиной низкой частоты кадров является background.draw()
. Переключение на Bitmap
несколько улучшает это, возможно, из-за того, что оно кэширует выходные данные draw()
и потому, что его можно использовать с Canvas
функциями, которые гарантированно не нуждаются в масштабировании (например, drawBitmap (Bitmap, float) , поплавок, краски) )
Вы также обнаружили, что переключение на RGB_565 в качестве промежуточного формата значительно повышает производительность, предположительно потому, что он отбрасывает альфа. (В противном случае, я бы ожидал, что это будет несколько медленнее, т.к. формат должен быть конвертирован обратно в RGBA_8888, поскольку он преобразован в SurfaceView
.)
Также очевидно, что Android не будет пропускать более 60 кадров в секунду. Это почти наверняка, потому что lockCanvas()
участвует в схеме тройной буферизации , которая регулирует частоту рисования, чтобы предотвратить отправку кадров, которые никогда не могут отображаться (из-за фиксированной частоты обновления экрана вашего устройства 60 Гц) .
Это оставляет вопрос, почему вы не получаете полных 60 кадров в секунду, но что-то близко к этому. Если для drawGameElements()
требуется одинаковое количество времени для запуска каждый раз, и оно меньше 16 мс, тогда lockCanvas()
должно задушить вас, и ни один кадр не должен пропадать (непрерывно 60 кадров в секунду). Кажется вероятным, что в планировщике потоков есть что-то вроде сбоя, и время от времени CannonThread
не выполняется достаточно быстро, чтобы предоставить кадр, прежде чем схеме тройной буферизации потребуется page-flip, В этом случае кадр должен быть отложен до следующего обновления экрана. Вы можете попытаться увеличить CannonThread's
приоритет потока , удалить любую дополнительную обработку в drawGameElements()
, которая не обязательно должна выполняться в CannonThread
, или закрыть другие приложения, работающие на вашем устройстве.
Как уже упоминалось, OpenGL является стандартным способом получения максимальной производительности спрайтов для подобных игр, поскольку он способен перегрузить многие операции на оборудование. Возможно, вы приближаетесь к пределу производительности игры на drawBitmap()
.