#android #bitmap
#Android #растровое изображение
Вопрос:
Я пытаюсь научиться создавать анимированные спрайты в Android и не могу понять, как организовать мои растровые изображения. У меня есть спрайтовый лист моего персонажа, идущего вправо: растровое изображение из пяти копий персонажа, расположенных на равном расстоянии (каждые 45 пикселей), в цикле обхода.
Я планировал рисовать каждый кадр, рисуя крошечную часть моего растрового изображения на листе спрайтов за раз, перейдя:
Rect sourceRect = new Rect(0, 0, 45, 75);
canvas.drawBitmap(spriteSheetBitmap, sourceRect, new Rect(0, 0, 45, 75), null);
Затем для следующих кадров увеличьте «sourceRect.x» на 45, затем перерисуйте и так далее.
Однако теперь я не уверен, как заставить мой спрайт двигаться влево. Сначала я думал, что могу просто отразить свой прямоугольник, из которого я рисую, чтобы получить перевернутое изображение. Что-то вроде:
sourceRect = new Rect(45, 0, 0, 75);
похоже, это не работает (не уверен, что на самом деле здесь происходит, но на моей поверхности ничего не рисуется).
Поиск в Интернете, кажется, я должен сделать копию моего исходного растрового изображения, отразить его с помощью матрицы преобразования, а затем использовать это растровое изображение для рисования при движении влево. Однако я также нашел реализации, в которых многие объекты bitmap меньшего размера создаются из исходного листа спрайтов, сохраняются (и преобразуются для зеркального движения), а затем используются по мере необходимости.
Итак, мне интересно, что было бы лучшим в этом случае или действительно ли есть какая-либо разница (производительность / память):
Метод 1: Загрузите мой исходный лист спрайтов, создайте новый экземпляр bitmap, зеркально отразите его, затем вычислите все прямоугольники и используйте эти два целых листа для рисования (по общему признанию, есть дополнительное пространство для растрового изображения, где лист спрайтов не используется).
Метод 2: Загрузите мой исходный лист спрайтов, для каждого кадра создайте два новых растровых объекта (1 зеркальный, 1 обычный) и сохраните их для рисования.
Метод 3: другие лучшие способы?
Ответ №1:
Метод 2 был бы слишком дорогим, и вам не нужен холст, чтобы перевернуть растровое изображение. Просто создайте другое растровое изображение с примененной матрицей, например:
BitmapDrawable flip(BitmapDrawable d)
{
Matrix m = new Matrix();
m.preScale(-1, 1);
Bitmap src = d.getBitmap();
Bitmap dst = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, false);
dst.setDensity(DisplayMetrics.DENSITY_DEFAULT);
return new BitmapDrawable(dst);
}
Комментарии:
1. Из того, что вы говорите, кажется, лучше использовать метод 1? Тогда лучше сохранить 2 экземпляра «большого» основного растрового изображения, а затем иметь много экземпляров растрового изображения: два экземпляра растрового изображения с разрешением 225 пикселей на 75 пикселей по сравнению с десятью экземплярами растрового изображения с разрешением 45 пикселей на 75 пикселей
2. Имейте много небольших экземпляров растрового изображения, поэтому в каждом кадре требуется меньше данных для чтения.
3. Я исправил зеркальный эффект с
matrix.preScale(1, -1)
помощью . По какой-то причинеmatrix.preScale(-1, 1)
зеркальное отображение изображения по вертикали.
Ответ №2:
Чтобы отразить ваш спрайт, просто примените следующее преобразование к холсту: масштаб (-1, 1). Вам также придется смещать спрайт по его ширине.
Комментарии:
1. Я тоже думал об этом, и для этого конкретного случая это может сработать, поскольку существует только один спрайт. Но если бы у меня было несколько спрайтов, предварительно нарисованных на холсте, и спрайты, которые нужно было нарисовать после, я полагаю, все перевернулось бы?
2. Просто используйте save() / restore(), чтобы применить / отменить эффект зеркального отображения.
3. 1 за указание на то, что растровому изображению требуется смещение (его ширина)!
4. @JaySoyer потому что, когда вы масштабируете на -1, а точка поворота равна 0, координата x вашего самого правого пикселя будет умножена на -1, поэтому она будет отрицательной (это будет -width ). Вот почему вам нужно переместить все ваши пиксели обратно в исходное положение 0. И это делается путем добавления ширины к координатам.
5. это определенно правильный путь. научитесь использовать матрицы для преобразований — они используются на всех известных мне платформах, с их помощью графический процессор вычисляет данные. Вы не хотите создавать растровое изображение для каждого преобразованного спрайта. Общий процесс таков: вы рисуете, используя обычную (обычно идентификационную) матрицу, а затем, когда вы хотите повернуть / перевернуть / масштабировать и т. Д. спрайт, Вы применяете новую матрицу, рисуете спрайт и возвращаетесь к своей предыдущей матрице. Просто для ясности: это не повлияет на ваши предыдущие нарисованные элементы.
Ответ №3:
Чтобы нарисовать вертикальное зеркальное растровое bmp
изображение на canvas
:
Matrix m = new Matrix();
// Mirror is basically a rotation
m.setScale( -1 , 1 );
// so you got to move your bitmap back to it's place. otherwise you will not see it
m.postTranslate(canvas.getWidth(), 0);
canvas.drawBitmap(bmp, m, p);