oshogbo//vx

My place in space

Android graphics alternative

Dec. 10, 2011, 9:46 a.m.

The standard method of using graphics is to use Canvas and Drawable and other funny things that I don't like (you can read about it at http://developer.android.com/guide/topics/graphics/2d-graphics.html).
The other way to read graphics in android is using "assets". What is it?

This is a special folder that can contain whatever we want. I think it's niceto know about this opportunity because in the res folder we can't create sub folders for graphics and also we must declare them in xml. For a person like me (who writes a little in OpenGL) that was not very intuitive. So I looked for another possibility and fortunately programmers from google gaveme one! You don't use some ImageView any more. You must write your own View it's not very complicated you need to override some methods (like the very important onDraw that is provided to us by Canvas and will be needed to draw our classes). Also we must write some bitmap loader. This isn't very complicated. We must have some handle to the resourses the simplest way is just make static Resurces in your graphic loader class. So our load method can look something like this:

public Bitmap load(String src) {

 Bitmap texture = null;
 
 try {
  InputStream is = resources.getAssets().open(src);
  texture = BitmapFactory.decodeStream(is);
 }catch(IOException e) {
  Log.d("Graphic error", "Could not read: " + src);
  return null;
 }
 
 return texture;
}


So it's very simple and quick. Ok, the next step we can do is to create some sub folders with animations for example if we have a fighter he have some graphic to die or dance. So for example we can create 5 textures in the folder dance that are called somehow (eg. dance1.png, dance2.png) and read all sub folders. So now our src will only contain the name of actor you want read and the action (eg. fighter/dance). Its also very simple:

public Bitmap[] load(String src) throws IOException {

 Bitmap[] texture = null;
 String[] names = resources.getAssets().list(src); // to get all files in folder
 texture = new Bitmap[ names.length ];

 for(int i = 0; i < names.length; i++) {
  InputStream is = resources.getAssets().open(src + "/" + names[i]);
  texture[i] = BitmapFactory.decodeStream(is);
 }

 return texture;
}

In the last version I want to present we will scale our texture. Why? We can make one texture with an approximate size (or the biggest one) and use it man times, ofc if we make the size of bitmap too small then on a big screen (eg. for a tablet) it will look very ugly so you must think about it or you can create some sub folder with alternative images and load them depending on the device's resolution. But now a version with scale.

public Bitmap[] load(String src, int width, int height) throws IOException {

 Bitmap[] texture = null;
 String[] names = resources.getAssets().list(src); // to get all files in folder
 texture = new Bitmap[ names.length ];

 for(int i = 0; i < names.length; i++) {
  InputStream is = resources.getAssets().open(src + "/" + names[i]);
  texture[i] = BitmapFactory.decodeStream(is);
  texture[i] = Bitmap.createScaledBitmap(texture[i], width, height, false);
 }

 return texture;
}


A good way to do it in the project is just to multiply width and height of texture (texture.getWidth()/getHeight()) by the ratio of the actual screen resolution and resolution at which this project was made. A good idea is to make all those textures static so that when creating many classes you will read them only one time (you will save a lot of memory). You can create some modifications to this function that will be more useful. To draw those textures we use a very simple method which we next use in our aplication logic:

public void draw(Canvas canvas)
{
 canvas.drawBitmap(texture, x, y, null);
}