Ответ 1
SurfaceView
SurfaceView
предназначен для использования при постоянном повторении и Drawable
не для этой цели.
Я только что кое-что узнал, и мне было интересно, как и почему. Я разрабатываю небольшую аркадную игру для Android. Я решил игнорировать OpenGL и использовать стандартные SurfaceView и Drawables, чтобы сделать это, так как он предположительно будет светлым (10 спрайтов или около того). У меня есть drawables, которые я загружаю, и использую метод Draw и передавая им свой холст. Это как каждый спрайт обращается к экрану. Хорошо получается, что рисунок 4-5 больших спрайтов (200X400 или около того) занимает много времени на менее чем новых моделях телефонов. Достаточно долго, чтобы моя игра была неиграбельной. Мы говорим о 50-60 миллисекундах для создания одного кадра с использованием этого метода. И я действительно ничего не делаю, кроме рисунка, и нигде я не могу сократить расходы. Поэтому я решил попробовать использовать Bitmaps. Здесь, однако, мне нужно предварительно задать размер, так как в растровом виде нет метода setBounds. Нет проблем, я изменяю их размер, чтобы соответствовать моему текущему экрану при загрузке, проблема решена.
OK. Поэтому у меня есть растровые изображения. Теперь я использую Canvas.DrawBitmap для рисования. Я скачу новый метод рисования.. и я получаю повышение эффективности 400%!. Вместо 50-60 мс весь цикл рисования теперь занимает 8-12 мс. Какого черта??? Чтобы исключить это, я тоже приурочил setBounds, он занимает < 1ms, чтобы он не виноват. Это фактический Drawable.Draw, который замедляет работу.
Для меня это отличная новость, так как я действительно не хотел изучать OpenGL, чтобы сделать игру более доступной, но я не могу перестать думать об этом - все в порядке? есть ли проблемы с моим методом? Почему он нигде не упоминается?
SurfaceView
SurfaceView
предназначен для использования при постоянном повторении и Drawable
не для этой цели.
Canvas.drawBitmap
работает намного меньше, чем Drawable.draw
, поэтому он быстрее.
Drawable.draw
Поскольку Drawable
является абстрактным классом, рассмотрим BitmapDrawable
:
public void draw(Canvas canvas) {
final Bitmap bitmap = mBitmapState.mBitmap;
if (bitmap == null) {
return;
}
final BitmapState state = mBitmapState;
final Paint paint = state.mPaint;
if (state.mRebuildShader) {
final Shader.TileMode tmx = state.mTileModeX;
final Shader.TileMode tmy = state.mTileModeY;
if (tmx == null && tmy == null) {
paint.setShader(null);
} else {
paint.setShader(new BitmapShader(bitmap,
tmx == null ? Shader.TileMode.CLAMP : tmx,
tmy == null ? Shader.TileMode.CLAMP : tmy));
}
state.mRebuildShader = false;
}
final int restoreAlpha;
if (state.mBaseAlpha != 1.0f) {
final Paint p = getPaint();
restoreAlpha = p.getAlpha();
p.setAlpha((int) (restoreAlpha * state.mBaseAlpha + 0.5f));
} else {
restoreAlpha = -1;
}
final boolean clearColorFilter;
if (mTintFilter != null && paint.getColorFilter() == null) {
paint.setColorFilter(mTintFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
}
updateDstRectAndInsetsIfDirty();
final Shader shader = paint.getShader();
final boolean needMirroring = needMirroring();
if (shader == null) {
if (needMirroring) {
canvas.save();
// Mirror the bitmap
canvas.translate(mDstRect.right - mDstRect.left, 0);
canvas.scale(-1.0f, 1.0f);
}
canvas.drawBitmap(bitmap, null, mDstRect, paint);
if (needMirroring) {
canvas.restore();
}
} else {
updateShaderMatrix(bitmap, paint, shader, needMirroring);
canvas.drawRect(mDstRect, paint);
}
if (clearColorFilter) {
paint.setColorFilter(null);
}
if (restoreAlpha >= 0) {
paint.setAlpha(restoreAlpha);
}
}
Вы можете видеть, что он даже вызывает Canvas.drawBitmap
внутренне.
Canvas.drawBitmap
Сравните это с Canvas.drawBitmap
. Это намного короче.
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
throwIfCannotDraw(bitmap);
native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top,
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}
Существует несколько различных методов drawBitmap
, но все они короче метода Drawable.draw
. Остерегайтесь ловушек как это, чтобы быстро сохранить рисунок растрового изображения.