web-dev-qa-db-fra.com

Dessin de bitmaps en miroir dans android

J'essaie d'apprendre à créer un Sprite animé en Android et je n'arrive pas à comprendre comment organiser mes bitmaps. J'ai une feuille Sprite de mon personnage qui marche vers la droite: une image bitmap de cinq copies d'un personnage, également espacées (tous les 45 px), dans un cycle de marche.

J'ai prévu de dessiner chaque image en dessinant une petite section de mon bitmap de feuille Sprite à la fois en allant:

Rect sourceRect = new Rect(0, 0, 45, 75);
canvas.drawBitmap(spriteSheetBitmap, sourceRect, new Rect(0, 0, 45, 75), null);

Ensuite, pour les images suivantes, incrémentez "sourceRect.x" de 45, puis redessinez et ainsi de suite.

Cependant, je ne sais pas maintenant comment faire pour que mon Sprite marche vers la gauche. J'avais d'abord pensé que je pouvais simplement refléter mon rectangle à partir duquel je dessine pour obtenir une image inversée. Quelque chose comme:

sourceRect = new Rect(45, 0, 0, 75);

ce qui ne semble pas fonctionner (je ne sais pas vraiment ce qui se passe ici, mais rien n'est attiré à ma surface).

En recherchant en ligne, il semble que je devrais faire une copie de mon bitmap d'origine, le mettre en miroir avec une matrice de transformation, puis utiliser ce bitmap pour dessiner en marchant vers la gauche. Cependant, j'ai également trouvé des implémentations où de nombreux objets bitmap plus petits sont créés à partir de la feuille Sprite d'origine, stockés (et transformés pour le mouvement en miroir), puis utilisés selon les besoins.

Je me demande donc quelle serait la meilleure dans ce cas ou s'il y a vraiment une différence (performances/mémoire):

Méthode 1: Charger dans ma feuille Sprite d'origine, créer une nouvelle instance bitmap, la mettre en miroir, puis calculer tous les rectangles et utiliser ces + deux feuilles entières pour dessiner (il y a certes un espace bitmap supplémentaire où la feuille Sprite n'est pas utilisée).

Méthode 2: Charger dans ma feuille Sprite d'origine, pour chaque image, créez deux nouveaux objets bitmap (1 en miroir, 1 normal) et stockez ceux à dessiner.

Méthode 3: D'autres meilleures façons?

25
mitim

La méthode 2 serait beaucoup trop chère et vous n'avez pas besoin d'un canevas pour retourner une image bitmap. Créez simplement un autre bitmap avec une matrice appliquée, comme ceci:

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);
}
71
user999717

Pour refléter votre Sprite, appliquez simplement la transformation suivante sur le canevas: échelle (-1, 1). Vous devrez également compenser le Sprite par sa largeur.

17
Romain Guy

Pour dessiner un bitmap miroir vertical bmp sur un 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);
3
PiTheNumber