4

For my useless project of the month I'm working on a 'emulator' to run J2ME programs on Android. But now I'm stuck with the J2ME Sprite implementation. Specifically the transformations used in it.

In my Sprite I have a bitmap with three character images. I would like to paint the second frame mirrored or rotated 90 degrees. What would be the best way for it?

I have following code that paints the given frame without any transformations.

frameX, frameY are frame position coordinates on give sprite bitmap.

Rect src = new Rect(frameX, frameY, frameX + spriteWidth, frameY + spriteHeight);
Rect dst = new Rect(paintX, paintY, paintX + spriteWidth, paintY + spriteHeight);
canvas.drawBitmap(image, src, dst, null);

As I understand I need to make some matrix magic on the canvas, but I have not been able to figure this out :)

JaanusSiim
  • 2,192
  • 3
  • 22
  • 24

3 Answers3

4

You do know that Microemulator, an open source project, makes it possible to run J2ME code on Android, right?

http://www.microemu.org/

You could always have a look and see what they do.

David N. Welton
  • 1,875
  • 18
  • 33
3

Went with splitting sprite into frames and using transformations with single image:

public final void paint(final Canvas canvas) {
  final Bitmap painted = images[frame];
  final Matrix matrix = createTransformationMatrix(transform);
  matrix.postTranslate(spriteX, spriteY);
  canvas.drawBitmap(painted, matrix, null);
}

private Matrix createTransformationMatrix(final int transform2) {
  final Matrix result = new Matrix();
  switch (transform2) {
  case TRANS_NONE:
    break;
  case TRANS_MIRROR_ROT180:
    result.setScale(-1, 1);
    result.postTranslate(getWidth(), 0);
    result.postRotate(180);
    break;
  case TRANS_MIRROR:
    result.setScale(-1, 1);
    result.postTranslate(getWidth(), 0);
    break;
  case TRANS_ROT180:
    result.postRotate(180);
    break;
  case TRANS_MIRROR_ROT270:
    result.setScale(-1, 1);
    result.postTranslate(getWidth(), 0);
    result.postRotate(270);
    break;
  case TRANS_ROT90:
    result.postRotate(90);
    break;
  case TRANS_ROT270:
    result.postRotate(270);
    break;
  case TRANS_MIRROR_ROT90:
    result.setScale(-1, 1);
    result.postTranslate(getWidth(), 0);
    result.postRotate(90);
    break;
  }
  return result;
}

Works like a charm :)

JaanusSiim
  • 2,192
  • 3
  • 22
  • 24
2

I haven't done any Android development, but a lot of mobile and a lot of Java in that mobile development. So take this with that in mind.

What I would do, after taking a look at the Android class docs (linked below), is the following:

Rect src = new Rect(frameX, frameY, frameX + spriteWidth, frameY + spriteHeight);
Rect dst = new Rect(paintX, paintY, paintX + spriteWidth, paintY + spriteHeight);
Matrix orig = canvas.getMatrix();
canvas.rotate(90.0f);
canvas.drawBitmap(image, src, dst, null);
canvas.setMatrix(orig);

Or you can do it like so:

RectF src = new RectF(frameX, frameY, frameX + spriteWidth, frameY + spriteHeight);
RectF dst = new RectF(paintX, paintY, paintX + spriteWidth, paintY + spriteHeight);
Matrix matrix = canvas.getMatrix();
matrix.rotate(90.0f);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.FILL);
canvas.drawBitmap(image, matrix, null);

Both methods seem good to me. I'm not sure if either is faster. The latter solution is a bit more modular since you never have to change the canvas's matrix. So, that might be considered the better solution.

Android Class Listing

Android Canvas Class

Android Matrix Class

Fostah
  • 11,398
  • 10
  • 46
  • 55