Browse through more Android tutorials. If you'd like to see a tutorial on any particular topic, do leave a comment in the wishlist page. We frequently post new tutorials along with app releases. You may subscribe to our newsletter to get all updates in your inbox.
Now you can get the latest Java source bundled with each app update. Install the app from Google Play and go to Settings > Extras.

«  Create an instant messaging app Create a reminder/alarm app  »

Create a game like Flappy Bird in Android using AndEngine

DownloadDownload

Keywords: AndEngine AndEnginePhysicsBox2DExtension SimpleBaseGameActivity ResourceManager SceneManager MenuScene CameraScene AutoParallaxBackground AnimatedSprite DynamicSpriteBatch TiledSprite Sound Music HUD Font PhysicsHandler GenericPool PhysicsWorld Fixture Body ContactListener

Contents

3 « Prev Page

8. Resource Manager

The ResourceManager class is designed to be a singleton so that it can manage all resources used in the game. Here is a basic outline of the class.





	public class ResourceManager {
		
		private static final ResourceManager INSTANCE = new ResourceManager();
		
		public GameActivity mActivity;
		
		private ResourceManager() {}
		
		public static ResourceManager getInstance() {
			return INSTANCE;
		}
		
		public void prepare(GameActivity activity) {
			INSTANCE.mActivity = activity;
		}
		
		public void loadSplashResources() {
			//TODO implement
		}
		
		public void unloadSplashResources() {
			//TODO implement
		}
		
		public void loadGameResources() {
			//TODO implement
		}
		
		public void unloadGameResources() {
			//TODO implement
		}    
		
	}
					
Usually, there is a load and corresponding unload method for each screen. Since our menu scene is lot similar to game scene so we have combined into a single method.

It is not recommended to load and unload resources frequently in a game. Only unload resources that are no longer needed.

In next few sections we'll discuss some common types of resources used in a game.

9. TextureAtlas & TextureRegion

TextureAtlas or just texture is kind of map that holds all images in the memory whereas TextureRegion is a portion of the map occupied by a specific image.
Let's now implement the empty methods by creating textures relevant to a scene. Add the below code to ResourceManager for loading textures used by splash scene.
    private BitmapTextureAtlas mSplashTextureAtlas;
    public ITextureRegion mSplashTextureRegion;
    
    public void loadSplashResources() {
    	BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/splash/");
    	mSplashTextureAtlas = new BitmapTextureAtlas(mActivity.getTextureManager(), 512, 512, TextureOptions.BILINEAR);
    	mSplashTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mSplashTextureAtlas, mActivity, "logo.png", 0, 0);
    	mSplashTextureAtlas.load();    	
    }
					
We need to create gfx folder under assets directory of the project for storing all graphics used in the game. Further, we create sub-folders under gfx for each scene.
First, we set the base path for all assets.
Next, we create an atlas with dimension that can hold all images and create regions within the atlas.

Keep in mind that the atlas dimension must be a power of 2 for efficient use of memory.

For splash scene we just have a single logo.png present in gfx/splash folder.
Corresponding to a load method we have unload method for unloading resources. Here is the code for unloading splash textures.
    public void unloadSplashResources() {
		mSplashTextureAtlas.unload();
		mSplashTextureRegion = null;
    }
					
We'll next do the same exercise for game scene.
	private BitmapTextureAtlas mAutoParallaxBackgroundTexture;
	public ITextureRegion mParallaxLayerBack;
	public ITextureRegion mParallaxLayerFront;
	
	private BitmapTextureAtlas mBitmapTextureAtlas;
	public TiledTextureRegion mBirdTextureRegion;
	public TiledTextureRegion mPipeTextureRegion;
	
	private BitmapTextureAtlas mSubBitmapTextureAtlas;
	public TiledTextureRegion mStateTextureRegion;
	public ITextureRegion mPausedTextureRegion;
	public ITextureRegion mResumedTextureRegion;
	public TiledTextureRegion mButtonTextureRegion;
	public TiledTextureRegion mMedalTextureRegion;
	
    public void loadGameResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/game/");
		
		mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(mActivity.getTextureManager(), 512, 1024);
		mParallaxLayerFront = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mAutoParallaxBackgroundTexture, mActivity, "Flappy_Ground.png", 0, 0);
		mParallaxLayerBack = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mAutoParallaxBackgroundTexture, mActivity, "Flappy_Background.png", 0, 150);
		mAutoParallaxBackgroundTexture.load();
		
		mBitmapTextureAtlas = new BitmapTextureAtlas(mActivity.getTextureManager(), 128, 512, TextureOptions.BILINEAR);
		mBirdTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, mActivity, "Flappy_Birdies.png", 0, 0, 1, 3);
		mPipeTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, mActivity, "Flappy_Pipe.png", 0, 125, 2, 1);
		mBitmapTextureAtlas.load();
		
		mSubBitmapTextureAtlas = new BitmapTextureAtlas(mActivity.getTextureManager(), 512, 512, TextureOptions.BILINEAR);
		mStateTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mSubBitmapTextureAtlas, mActivity, "ready_over.png", 0, 0, 2, 1);
		mPausedTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mSubBitmapTextureAtlas, mActivity, "board.png", 0, 60);
		mResumedTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mSubBitmapTextureAtlas, mActivity, "help.png", 0, 200);
		mButtonTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mSubBitmapTextureAtlas, mActivity, "play_pos.png", 0, 350, 2, 1);
		mMedalTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mSubBitmapTextureAtlas, mActivity, "medal.png", 0, 450, 4, 1);
		mSubBitmapTextureAtlas.load();
    }
    
    public void unloadGameResources() {
		mAutoParallaxBackgroundTexture.unload();
		mBitmapTextureAtlas.unload();
		mSubBitmapTextureAtlas.unload();
		
		mAutoParallaxBackgroundTexture = null;
		mParallaxLayerFront = null;
		mParallaxLayerBack = null;
		
		mBitmapTextureAtlas = null;
		mBirdTextureRegion = null;
		mPipeTextureRegion = null;
		
		mSubBitmapTextureAtlas = null;
		mStateTextureRegion = null;
		mPausedTextureRegion = null;
		mResumedTextureRegion = null;
		mButtonTextureRegion = null;
		mMedalTextureRegion = null;
    }	
					
Game scene uses much more textures but the basic concept is the same. The important thing to keep in mind is the atlas dimension and correct positioning of regions within it.

You may use BlackPawnTextureAtlasBuilder and BuildableBitmapTextureAtlas for automated positioning of regions in an atlas.

If you are wondering why we used multiple atlases, its just the way the game evolved. The idea should be to utilize maximum area within an atlas since its consuming memory.

10. Font

AndEngine allows us to use default fonts (monospace, serif, sans-serif, etc.) as well as custom fonts (.ttf) in a game.
Here is a code snippet to load and unload default font to be used in splash scene.
    public Font mFont1;
    
    public void loadSplashResources() {
    	//...
    	
		mFont1 = FontFactory.create(mActivity.getFontManager(), mActivity.getTextureManager(), 256, 256, Typeface.create(Typeface.DEFAULT, Typeface.NORMAL), 10, Color.GRAY);
		mFont1.load();    	
    }
    
    public void unloadSplashResources() {
		//...
		
    	mFont1.unload();
    	mFont1 = null;
    }
					
We can specify the typeface, style, size, and color while creating the font.
Next, we'll see how to create custom font needed in the game scene.
    public Font mFont2;
    public Font mFont3;
    public Font mFont4;
    public Font mFont5;

    public void loadGameResources() {
    	//...	
	
		mFont4 = FontFactory.create(mActivity.getFontManager(), mActivity.getTextureManager(), 256, 256, Typeface.create(Typeface.DEFAULT, Typeface.NORMAL), 16, Color.BLACK);
		mFont4.load();		
		
		FontFactory.setAssetBasePath("font/");
		ITexture fontTexture2 = new BitmapTextureAtlas(mActivity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
		mFont2 = FontFactory.createStrokeFromAsset(mActivity.getFontManager(), fontTexture2, mActivity.getAssets(), "Font1.ttf", 40, true, Color.YELLOW, 2, Color.DKGRAY);
		mFont2.load();
		
		ITexture fontTexture3 = new BitmapTextureAtlas(mActivity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
		mFont3 = FontFactory.createFromAsset(mActivity.getFontManager(), fontTexture3, mActivity.getAssets(), "Font2.ttf", 24, true, Color.WHITE);
		mFont3.load();
		
		ITexture fontTexture5 = new BitmapTextureAtlas(mActivity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
		mFont5 = FontFactory.createStrokeFromAsset(mActivity.getFontManager(), fontTexture5, mActivity.getAssets(), "Font1.ttf", 36, true, Color.WHITE, 2, Color.DKGRAY);
		mFont5.load();		
    }
    
    public void unloadGameResources() {
    	//...
	
    	mFont4.unload();
    	mFont4 = null;    	
    	
    	mFont2.unload();
    	mFont2 = null;
    	
    	mFont3.unload();
    	mFont3 = null;
    	
    	mFont5.unload();
    	mFont5 = null;    	
    }
					
We need to create font folder under assets directory of the project for storing all .ttf files used in the game.
Note that we created stroke font (with outline) using createStrokeFromAsset() and normal font using createFromAsset().

11. Sound & Music

Recall that earlier we had enabled sound and music while creating engine options in onCreateEngineOptions() method of GameActivity.
Here is the code snippet to load/unload sound and music. We will discuss how to play them in a later section.
	public Sound mSound;
	public Music mMusic;

    public void loadGameResources() {
		//...
		
		SoundFactory.setAssetBasePath("mfx/");
		try {
			mSound = SoundFactory.createSoundFromAsset(mActivity.getEngine().getSoundManager(), mActivity, "metal_hit.ogg");
		} catch (final IOException e) {
			Debug.e(e);
		}
		
		MusicFactory.setAssetBasePath("mfx/");
		try {
			mMusic = MusicFactory.createMusicFromAsset(mActivity.getEngine().getMusicManager(), mActivity, "bird_sound.ogg");
			mMusic.setLooping(true);
		} catch (final IOException e) {
			Debug.e(e);
		}
    }
    
    public void unloadGameResources() {
		//...
	
		mSound.release();
		mSound = null;
		
		mMusic.stop();
		mMusic.release();
		mMusic = null;
    }
					
We need to create mfx folder under assets directory of the project for storing all audio files used in the game.
Share the love:  

Next Page » 3

App Gen
App Name:
Project Name:
Package:
Screens:
Splash
Login
Help
Main
List  Grid  Pager
Detail
Settings
Options:
Action Bar
Navigation Drawer
Dummy Data
Generate
Free Apps