У меня нет 2D-графики и игровых возможностей. Я учил себя сотнями ошибок и десятков утраченных часов. Я начал с простой игры Dress Up. Я использовал Nexus 5x для разработки, где экран выглядел нормально. Когда я закончил одну веху, я попробовал игру на большом планшете Lenovo и миниатюрном телефоне Samsung Mini. Это выглядело ужасно.
Оригинальный векторный PSD файл выглядит превосходно, экспорт PNG также не имеет проблем. Но когда я масштабирую картину, она ухабистая. Я знаю, что это растровое изображение. Но есть другая картина, которую я масштабирую в другом месте, и она выглядит нормально (обе фотографии 32 бит):
Когда я играю в какую-либо игру из Google Play, у них никогда не бывает проблем с масштабированием. Как они реализованы? Используют ли они векторы? Есть ли какой-то трюк?
Я поместил все в папку assets
, и хотя это заняло 1 МБ. Я декомпилировал некоторые apk, и у них нет набора вариантов для каждого разрешения. Хотя они хорошо масштабируют изображения.
Некоторые фрагменты исходного кода:
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.w = w;
this.h = h;
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
protected void onDraw(Canvas canvas) {
if (baseBitmap != null) {
double scale = Math.min((double) w / (double) figure.getW(), (double) h / (double) figure.getH());
figure.setScaleRatio(scale);
int sw = (int) (scale * figure.getW());
int x = ((w - sw) >> 1);
figure.setX(x);
paintDressPart(canvas, figure, figure.getMain());
if (displayedParts != null) {
for (DressPart dressPart : figure.getParts()) {
if (displayedParts.contains(dressPart.getId())) {
paintDressPart(canvas, figure, dressPart);
}
}
}
}
}
private void paintDressPart(Canvas canvas, Figure figure, DressPart part) {
double scale = figure.getScaleRatio();
int sh = (int) (scale * part.getH());
int sw = (int) (scale * part.getW());
int sdx = (int) (scale * part.getDestX());
int sdy = (int) (scale * part.getDestY());
scaledRect.set(figure.getX() + sdx, sdy, figure.getX() + sw + sdx, sh + sdy);
Rect partRect = part.getRect();
canvas.drawBitmap(baseBitmap, partRect, scaledRect, canvasPaint);
}
И если вы хотите увидеть это самостоятельно, я подготовил полный проект на GitHub, чтобы вы могли скачать его и запустить сам:
https://github.com/literakl/DressUp
Обновление
Уменьшение масштаба также засасывает. Но благодаря замечанию Паавнна я понял, что Краска имеет значение. См. Разницу на картинке:
Я запускал демонстрационное приложение на 3,2-дюймовом AVD-изображении. Изображение 278x786 масштабируется до 107x303.
Обновление октябрь
Я переписал приложение, чтобы использовать папку ресурсов вместо активов. Android масштабирует фотографии, а затем я снова масштабирую их. Хотя он выглядит лучше, чем когда я не использую масштабирование ресурсов Android. Ресурсы масштабированного изображения выглядят обычно лучше, чем немасштабированное изображение nodpi/assets.
Я обнаружил, что mdpi работает лучше всего. У меня даже были снимки xxhdpi, и это выглядело хуже, чем mdpi. Я думаю, что даже на устройстве xxhdpi! Но это может быть проблемой картины, что она не была хорошо нарисована. Масштабирование ресурсов Android может сглаживать ребра на линиях.