Dealing with various screen sizes in AndEngine based Games

Android devices are very much fragmented. Here are some approaches how to deal with multiple screen resolutions when you are planning to make game using AndEngine framework.

Android devices greatly vary in screen sizes and resolution, from tiny 3.5 inches smartphones to huge 10 inches tablets in screen size. So it's very challenging to develop a game using AndEngine, that looks good for every possible screen sizes and resolutions.

AndEngine, open source game engine for android is very good at handling various screen sizes. It allows your game scene to be automatically scaled up or scaled down to fit the device in which it is running.

Here are few approaches how to deal with different screen sizes and resolutions.

Using fixed sized image resources.

This is the most simple and possibly widely used approach. Fixed sized camera is defined for all devices and let the framework do automatically scale using either FillResolution, RelativeResolutionPolicy or CropResolution policy. The main drawback here is image quality sufferers greatly in high end devices if you are using low resolution images. Or if you are using high resolution images, low end devices may suffer from performance. Either you have to develop for two or more (low end devices and high end devices) versions or develop for intermediate devices.

camera = new BoundCamera(0, 0, 480 , 800);
        EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new CropResolutionPolicy(480 , 800 ), this.camera);

Using vector graphics

The second approach is to use the vector images. Vector images retain the image quality no matter how much you zoom it. Using vector graphics can be best suited for simple games (graphics that don’t require too much details). Here are some drawbacks of using vector graphics

  • Creating vector images to suit all kind of objects (if objects have some high levels of details), requires lots of time and effort.
  • Vector graphics are not directly supported. AndEngineSVGTextureRegionExtension extension helps you use vector graphics inside AndEngine based game but it has to convert vector images to bitmaps on the fly. So startup time for the game will be noticeably higher.

Using vector graphics in your AndEngine based game is simple. Instead of BitmapTextureAtlasTextureRegionFactoryyou use SVGBitmapTextureAtlasTextureRegionFactory. Also you have to set the scalingFactor before loading any svg graphics.

  SVGBitmapTextureAtlasTextureRegionFactory.setScaleFactor(scaleFactor);
    game_background_region = SVGBitmapTextureAtlasTextureRegionFactory.createFromAsset(game_backgroundTextureAtlas, activity, "background.svg", 480, 800, 0, 0);

Use different sets of png images.

This is the best approach for developing game to target every possible screen sizes without compromising any image quality and performance issue. It takes advantage of both the above mentioned methods. Instead of using AndEngine to automatically convert vectors graphics to bitmaps on the fly, developer should create different resolution image resources for each set of devices. A single set may be group of devices which resolution ranges from 240320 to 800480. 3-4 set of image resources will be enough to feed the entire android variations.

Simply you put each set of image resources on different folder on the assets/gfx folder and decide which folder to use in runtime. Here is the example code.

For this approach, game graphics should be designed in the highest resolution, and we create different set of image resources for each ScaleFactor. ScaleFactor is set dynamically depending upon the device’s resolution. In this example i used three predefined scaleFactors (0.5,1,2).

float scaleFactor;
private void measureScaleFactor() {
    DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
    int widthPixels = Math.max(displayMetrics.widthPixels,displayMetrics.heightPixels);
    scaleFactor = 1;
    if(widthPixels<=1024){
        scaleFactor=0.5f;
    }
    else if (widthPixels <= 1280) {
        scaleFactor = 1f;
    } else if (widthPixels <= 1920) {
        scaleFactor = 1.5f;
    }
    else {
        scaleFactor=2f;
    }

}

Set the different assets folder dynamically

 float gfxLoc= "gfx/scalehalfx/";
 if(scaleFactor==1)
 {
 gfxLoc="gfx/scale1x/";
 }
if(scaleFactor==1.5)
 {
 gfxLoc="gfx/scale1_5x/";
 }
else if if(scaleFactor==2)
 {
 gfxLoc="gfx/scale2x/";
}
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath( gfxLoc);

How to generate different set of image resources automatically.

For this approach, game graphics should be designed in the highest resolution, and we create different set of image resources for each ScaleFactor (for eg: 0.5x,1x,1.5x,2x). Once you create the image resources for the highest resolution (2x in this example), there are some tools to easily convert them to other resolutions. I personally use ImageMagick to resize the whole folder using a single command. Here is the command to scale down all images residing on a folder to 50% .

//scale down for 1x (if you have designed in 2x resolution).
mogrify -resize 50% -format png *

Like us

See also

Modeling tools for Unity 3D

Here are some popular modeling tools for Unity 3D game development.