Monday, March 17, 2014

Create a Stone Class

In this post we are going to create a Stone class, stone class will be used to initialize our stone for the game. By creating a stone in a class we reduce the efforts to create stone again and again for different levels. We can just create a variable in GameScene and have our stone created. So lets start.

1. Create new class Stone

package com.mindew.fruitecollector;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

public class Stone extends Sprite{
private PhysicsHandler mPhysicsHandler;
private float originX, originY;

public Stone(float pX, float pY,Camera camera, ITextureRegion pTextureRegion,
VertexBufferObjectManager vbom) {

super(pX, pY, pTextureRegion, vbom);
// TODO Auto-generated constructor stub
mPhysicsHandler = new PhysicsHandler(this);
registerUpdateHandler(mPhysicsHandler);

originX = pX;
originY = pY;
this.setUserData("stone");
}

@Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY)
{
if (pSceneTouchEvent.isActionMove() || pSceneTouchEvent.isActionDown() || pSceneTouchEvent.isActionOutside())
{

float radius = 50;
Float distance = (pSceneTouchEvent.getX() - originX)*(pSceneTouchEvent.getX() - originX) + (pSceneTouchEvent.getY() - originY) * (pSceneTouchEvent.getY() - originY);
       distance = (float) Math.sqrt(distance);
       if(distance < radius)
       {
this.setX(pSceneTouchEvent.getX() - this.getWidth() / 2);
this.setY(pSceneTouchEvent.getY() - this.getHeight() / 2);
       }

}
else if (pSceneTouchEvent.isActionUp())
{
mPhysicsHandler.setVelocityX((originX - getX()) * 15);
mPhysicsHandler.setVelocityY((originY - getY()) * 10);
mPhysicsHandler.setAccelerationY(100);
}
return true;
}


}
Explanations: In above class  originX and originY variables are used to get the original coordinates of the stone when it is first created, it might be very useful sometimes. 
Then we defined the constructor for class and initialize the variables.
Then we are overriding the method called onAreaTouched and put the code for flinging the stone, by this code we can have a drag and throw effect for the stone.

So we are ready with our Stone class, now go back to the GameScene class and use it.

Define stone as,
Stone stone;

Create a method called createStone() as below,
public void createStone()
{
stone = new Stone(100,300,camera,resourcesManager.stone_region,vbom)
{
@Override
   protected void onManagedUpdate(float pSecondsElapsed) {
           // TODO Auto-generated method stub
           super.onManagedUpdate(pSecondsElapsed);
           if(this.mX + this.getWidth() < 0 || this.mX - this.getWidth() > 800 || this.mY + this.getWidth() < 0 || this.mY - this.getWidth() > 480)
           {
            this.detachSelf();
            levelfail.display(levelID,GameScene.this, camera);
            registerTouchArea(levelfail.yes);
            registerTouchArea(levelfail.no);
           
           }
          
           
   }
};
attachChild(stone);
stone.setCullingEnabled(true);
registerTouchArea(stone);
}

Now create a fruit,
Sprite fruit;

And create a method called createFruit()
public void createFruit()
{
fruit = new Sprite(600,150,resourcesManager.fruite_region,vbom)
{
@Override
   protected void onManagedUpdate(float pSecondsElapsed) {
           // TODO Auto-generated method stub
           super.onManagedUpdate(pSecondsElapsed);
           if(stone.collidesWith(this) )
           {
            //totalApple += 1;
            addToScore(100);
            //SaveManager.getInstance().setLevelOneScore(score);
            //SaveManager.getInstance().setTotalApple(totalApple);
               this.setIgnoreUpdate(true);
              //  levelCompleteWindow.display(StarsCount.THREE, GameScene.this, camera,1);
               //registerTouchArea(levelCompleteWindow.replay);
              //  registerTouchArea(levelCompleteWindow.home);
               //registerTouchArea(levelCompleteWindow.next);
            final FixtureDef PLAYER_FIX = PhysicsFactory.createFixtureDef(100.0f,0.3f, 0.0f);
        Body body = PhysicsFactory.createCircleBody(physicsWorld, fruite,BodyType.DynamicBody, PLAYER_FIX);
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(fruite,body, true, false));
       
        final FixtureDef PLAYER_FIX2 = PhysicsFactory.createFixtureDef(100.0f,0.3f, 0.0f);
        Body stonebody = PhysicsFactory.createCircleBody(physicsWorld, stone,BodyType.DynamicBody, PLAYER_FIX2);
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(stone,stonebody, true, false));
           }
           
   }
};
fruit.setCullingEnabled(true);
attachChild(fruit);
}

Finally go to createScene() method and put our created methods inside it,

public void createScene() {
// TODO Auto-generated method stub
createBackground();
   createHUD();
   createPhysics();
   createStone();
   createFruite();
   createWalls();
   setTouchAreaBindingOnActionDownEnabled(true); 
}
setTouchAreaBindingOnActionDownEnabled(true);  method is very useful when you do not want any interruption while dealing with single sprite or object.

So we are done, run the project and see if you can drag and throw the stone freely. The result you should see is when you fling/throw the stone and if it collides with fruit score 100 should be added to score text. Both fruit and stone should get fall down to the ground to simulate physics environment.

In the next post we are going to see how to load levels from .lvl files.
Enjoy! 

IMP: Creating GameScene class

So finally we are going to start coding for most important part of our game, the GameScene class.

* Create new class, called GameScene and use our BaseScene as a extension.

package com.mindew.fruitecollector;

import com.mindew.fruitecollector.BaseScene;
import com.mindew.fruitecollector.SceneManager.SceneType;

public class GameScene extends BaseScene
{
    @Override
    public void createScene()
    {
     
    }

    @Override
    public void onBackKeyPressed()
    {
     
    }

    @Override
    public SceneType getSceneType()
    {
        return SceneType.SCENE_GAME;
    }

    @Override
    public void disposeScene()
    {
     
    }
}
Now let’s check out the graphics used,
loneback.png

stone.png

fruit.png


Go to ResourcesManager class and initialize graphics,
public ITextureRegion lonebackgound_region;
   // public ITextureRegion cloud_region; //no need of this (you can still use if you wish)
    public ITextureRegion stone_region;
    public ITextureRegion stonearea_region;
    public ITextureRegion stoneleft_region;
    public ITextureRegion anchor_region;
    public ITextureRegion fruite_region;
    private BuildableBitmapTextureAtlas gameTextureAtlas;
    private BuildableBitmapTextureAtlas stoneTextureAtlas;
Inside load game graphics put the below code,
private void loadGameGraphics()
    {
     BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/game/");
        gameTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
        stoneTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 32, 32, TextureOptions.BILINEAR);
     
        lonebackgound_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "loneback.png");
        //cloud_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, //"cloud.png");
        stone_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(stoneTextureAtlas, activity, "stone.png");
        stonearea_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "bucket.png");
        stoneleft_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "stoneleft.png");
        fruite_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "fruite.png");
        anchor_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(gameTextureAtlas, activity, "anchor.png");
     

        try
        {
            this.gameTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
            this.gameTextureAtlas.load();
            this.stoneTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
            this.stoneTextureAtlas.load();
        }
        catch (final TextureAtlasBuilderException e)
        {
            Debug.e(e);
        }
    }

We are done loading the textures and our graphics for game.

2. Now go to GameScene class and Create the background method as below,
private void createBackground()
{
attachChild(backgr = new Sprite(0, 0, resourcesManager.lonebackgound_region, vbom)
{
   @Override
   protected void preDraw(GLState pGLState, Camera pCamera) 
   {
      super.preDraw(pGLState, pCamera);
      pGLState.enableDither();
   }
});
backgr.setCullingEnabled(true);
}


3. Loading custom fonts for displaying game scores. Do this as below,
> Download .ttf font file from any of the free website (I recommend www.1001freefonts.com)
> Create a new folder inside assets folder callsed font and put .ttf file inside it.
> Go to ResourcesManager class and define font variable,
public Font scorefont;
> Create a method as below,
private void loadScoreFonts()

    {

ontFactory.setAssetBasePath("font/");


Ffinal ITexture scoreFontTexture = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

scorefont = FontFactory.createStrokeFromAsset(activity.getFontManager(), scoreFontTexture, activity.getAssets(), "scorefont.ttf", 30, true, Color.WHITE, 2, Color.BLACK);

scorefont.load();


}

Now our score font is ready to use in game.

3. Go back to GameScene class and Create a HUD, which will be used for displaying game controller and score text. HUD objects will always be displayed at higher level on scene.

create new private field for HUD, and method to initialize it.

private HUD gameHUD;

private void createHUD()
{
    gameHUD = new HUD();
    camera.setHUD(gameHUD);
}

// CREATE SCORE TEXT

private Text scoreText;

private void createHUD()
{
    gameHUD = new HUD();
    
    // CREATE SCORE TEXT
    scoreText = new Text(20, 420, resourcesManager.font, "Score: 0123456789", new TextOptions(HorizontalAlign.LEFT), vbom);
    scoreText.setAnchorCenter(0, 0);    
    scoreText.setText("Score: 0");
    gameHUD.attachChild(scoreText);
    
    camera.setHUD(gameHUD);
}

create new integer field to keep our score count, and new method responsible for manipulating with score:
private int score = 0;

private int score = 0;

private void addToScore(int i)
{
    score += i;
    scoreText.setText("Score: " + score);
}


4. Creating physics:

We will need physics in our game, so lets create it.

create new field for our PhysicsWorld and create method to initialize it.

private PhysicsWorld physicsWorld;

private void createPhysics()
{
   physicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0, SensorManager.GRAVITY_EARTH), false); 
   registerUpdateHandler(physicsWorld);
}

Now create wall,

private void createWalls() {
        // TODO Auto-generated method stub
        FixtureDef WALL_FIX = PhysicsFactory.createFixtureDef(0.0f, 0.0f, 0.0f);
        Rectangle ground = new Rectangle(0, 480, 800,
                15, this.engine.getVertexBufferObjectManager());
        ground.setColor(new Color(15, 50, 0));
        PhysicsFactory.createBoxBody(physicsWorld, ground, BodyType.StaticBody,
                WALL_FIX);
        attachChild(ground);
        ground.setCullingEnabled(true);
    }
 
execute all creation methods inside createScene() method:

@Override
public void createScene()
{
    createBackground();
    createHUD();
    createPhysics();
    createWalls();
}

5. Displaying loading scene while loading game scene:
    Loading and unloading menu texture(s):

* As mentioned we will need methods responsible for handling unloading and loading level menu texture(s), create them inside our ResorucesManager class:

public void unloadLMenuTextures()
{
    lmenuTextureAtlas.unload();
}
    
public void loadMenuTextures()
{
    lmenuTextureAtlas.load();
}
Its quite self-explanatory what it just help us to free some memory while texture is currently not needed, later we can load it again with one line (we do not have to recreate texture regions etc, we just unloaded texture from memory, we can load it again) 
* create method inside SceneManager responsible for displaying loading scene, while initializing game scene and loading its resources, and unloading menu texture.

public void loadGameScene(final Engine mEngine)
{
    setScene(loadingScene);
    ResourcesManager.getInstance().unloadLMenuTextures();
    mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
    {
        public void onTimePassed(final TimerHandler pTimerHandler) 
        {
            mEngine.unregisterUpdateHandler(pTimerHandler);
            ResourcesManager.getInstance().loadGameResources();
            gameScene = new GameScene();
            setScene(gameScene);
        }
    }));
}


6. Now to use Game scene go back to the LevelMenuScene class and uncomment the line in override method onMenuItemClicked as below,

case MENU_LONE:
         SceneManager.getInstance().loadGameScene(engine);
return true;


BRAVO!!!
Above we just created the game background, HUD, defined physics,  and attached Score Text.
Run the project and see if you can run the  GameScene.
Enjoy!!!

Create a Loading Scene

1. Loading scene:

It will be a simple white scene, with only one object - text saying "loading..." - we will display this scene while pre-loading the game scene and its resources. Please refer to the class diagram from article number 2 (while displaying loading scene, menu textures will be unloaded, game resources will be loaded, and game scene will be initialized) This scene will be also used to get back to the menu scene  from the game scene (vice versa, unloading game scene and its textures and loading menu textures) By using this simple approach, we will minimize memory usage.

lets first create a loading scene class, lets call it LoadingScene. As previously, use our BaseScene class as an extension and add unimplemented methods.  Lets also create a white background for our scene.

package com.mindew.fruitecollector;

import org.andengine.entity.scene.background.Background;
import org.andengine.util.adt.color.Color;

import com.mindew.fruitecollector.BaseScene;
import com.mindew.fruitecollector.SceneManager.SceneType;

public class LoadingScene extends BaseScene
{
    @Override
    public void createScene()
    {
        setBackground(new Background(Color.WHITE));
    }

    @Override
    public void onBackKeyPressed()
    {
        return;
    }

    @Override
    public SceneType getSceneType()
    {
        return SceneType.SCENE_LOADING;
    }

    @Override
    public void disposeScene()
    {

    }
}

As you probably noticed, inside onBackKeyPressed() we just return, which means we do not perform any actions (because we do not want to do anything while the loading scene is being displayed and the player touches the phone`s back button)


3. Creating "loading..." text:

As I stated at the beginning, we will need text saying "loading..." to do this, we will first have to load some font to create the text.  Its up to you what kind of font you will use.

Open our ResourcesManager class, lets create a new method responsible for loading our Font, we also create our Font in a public field.

public Font font;

private void loadMenuFonts()
{
    FontFactory.setAssetBasePath("font/");
    final ITexture mainFontTexture = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

    font = FontFactory.createStrokeFromAsset(activity.getFontManager(), mainFontTexture, activity.getAssets(), "font.ttf", 50, true, Color.WHITE, 2, Color.BLACK);
    font.load();
}

I am loading a font called font.ttf from the assets/font/ folder.

Now lets execute our method responsible for loading fonts inside the loadMenuResources() method, so it should now look like this:

public void loadMenuResources()
{
    loadMenuGraphics();
    loadMenuAudio();
    loadMenuFonts();
}

The code responsible for loading font is ready, lets go back to our loading scene class, and create a Text object and place it in the middle of the screen.

@Override
public void createScene()
{
    setBackground(new Background(Color.WHITE));
    attachChild(new Text(400, 240, resourcesManager.font, "Loading...", vbom));
}

Initialize the loading scene inside our SceneManager, inside createMenuScene()

public void createMenuScene()
{
    ResourcesManager.getInstance().loadMenuResources();
    menuScene = new MainMenuScene();
    loadingScene = new LoadingScene();
    SceneManager.getInstance().setScene(menuScene);
    disposeSplashScene();
}

That's all for now, we will not use it yet as we will have to create a game scene first, and later code responsible for displaying the loading scene when necessary (see the code diagram to understand when the loading scene will be displayed)

Creating level selector scene

Level selector scene would be same as previously created man menu scene only the difference is buttons we are using.
So lets have a look at the graphics we are using,
lmenuback,png
lone.png
You can create your own png files for your project, so go ahead and create other buttons for level 2 to 5 and name it as ltwo.png, lthree.png etc.

Now go to resources manager class and initialize textures as below,
public ITextureRegion lmenu_background_region;
    public ITextureRegion lone_region;
    public ITextureRegion ltwo_region;
    public ITextureRegion lthree_region;
    public ITextureRegion lfour_region;
    public ITextureRegion lfive_region;
    private BuildableBitmapTextureAtlas lmenuTextureAtlas;

create a method as below,
private void loadLMenuGraphics()
    {
    BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/menu/");
    lmenuTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
    lmenu_background_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "lmenuback.png");
    lone_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "lone.png");
    ltwo_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "ltwo.png");
    lthree_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "lthree.png");
    lfour_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "lfour.png");
    lfive_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "lfive.png");
    levelfail_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "levelfail.png");
         yes_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "yes.png");
         no_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(lmenuTextureAtlas, activity, "no.png");
          
    try 
    {
       this.lmenuTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
       this.lmenuTextureAtlas.load();
   
    catch (final TextureAtlasBuilderException e)
    {
           Debug.e(e);
    }
    }

We are done loading the graphics for our level selector scene.

Now we need to define and initialize level selector scene in SceneManager class, go to scene manager class and follow below steps:
> Create variable,
private BaseScene lmenuScene;
> Inside enum SceneType create,
SCENE_LMENU
>Inside method setScene(SceneType sceneType) create case,
case SCENE_LMENU:
               setScene(lmenuScene);
               break;

>Create a new method as below,
public void createLMenuScene()
   {
       ResourcesManager.getInstance().loadMenuResources();
       lmenuScene = new LevelMenuScene();
       loadingScene = new LoadingScene();
       setScene(lmenuScene);
   }
Done
Ignore the errors for now, we gonna create the new class called LevelMenuScene as below,
package com.mindew.fruitecollector;

import org.andengine.entity.scene.menu.MenuScene;
import org.andengine.entity.scene.menu.MenuScene.IOnMenuItemClickListener;
import org.andengine.entity.scene.menu.item.IMenuItem;
import org.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.andengine.entity.scene.menu.item.decorator.ScaleMenuItemDecorator;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.util.GLState;
import org.andengine.engine.camera.*;

import com.mindew.fruitecollector.SceneManager.SceneType;

public class LevelMenuScene extends BaseScene implements IOnMenuItemClickListener{
private MenuScene menuChildScene;
private final int MENU_LONE = 0;
private final int MENU_LTWO = 1;
private final int MENU_LTHREE = 2;
private final int MENU_LFOUR = 3;
private final int MENU_LFIVE = 4;
@Override
public void createScene() {
// TODO Auto-generated method stub
createBackground();
createMenuChildScene();
}

@Override
public void onBackKeyPressed() {
// TODO Auto-generated method stub
disposeScene();
SceneManager.getInstance().loadMenuScene(engine);
}

@Override
public SceneType getSceneType() {
// TODO Auto-generated method stub
return SceneType.SCENE_LMENU;
}

@Override
public void disposeScene() {
// TODO Auto-generated method stub

}
private void createBackground()
{
   attachChild(new Sprite(0, 0, resourcesManager.lmenu_background_region, vbom)
   {
       @Override
       protected void preDraw(GLState pGLState, Camera pCamera)
       {
           super.preDraw(pGLState, pCamera);
           pGLState.enableDither();
       }
   });
}
private void createMenuChildScene()
{
   menuChildScene = new MenuScene(camera);
   menuChildScene.setPosition(0, 0);
 
   final IMenuItem loneMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_LONE, resourcesManager.lone_region, vbom), 1.2f, 1);
   final IMenuItem ltwoMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_LTWO, resourcesManager.ltwo_region, vbom), 1.2f, 1);
   final IMenuItem lthreeMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_LTHREE, resourcesManager.lthree_region, vbom), 1.2f, 1);
   final IMenuItem lfourMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_LFOUR, resourcesManager.lfour_region, vbom), 1.2f, 1);
   final IMenuItem lfiveMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_LFIVE, resourcesManager.lfive_region, vbom), 1.2f, 1);
 
   menuChildScene.addMenuItem(loneMenuItem);
   menuChildScene.addMenuItem(ltwoMenuItem);
   menuChildScene.addMenuItem(lthreeMenuItem);
   menuChildScene.addMenuItem(lfourMenuItem);
   menuChildScene.addMenuItem(lfiveMenuItem);
 
   menuChildScene.buildAnimations();
   menuChildScene.setBackgroundEnabled(false);
 
   loneMenuItem.setPosition(100,120);
   ltwoMenuItem.setPosition(220,120);
   lthreeMenuItem.setPosition(340,120);
   lfourMenuItem.setPosition(460,120);
   lfiveMenuItem.setPosition(580,120);
 
   menuChildScene.setOnMenuItemClickListener(this);
 
   setChildScene(menuChildScene);
}

@Override
public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
float pMenuItemLocalX, float pMenuItemLocalY) {
// TODO Auto-generated method stub
switch(pMenuItem.getID())
        {
        case MENU_LONE:
        //SceneManager.getInstance().loadGameScene(engine);
            return true;
        case MENU_LTWO:
        //SceneManager.getInstance().loadLevelTwoScene(engine);
            return true;
        case MENU_LTHREE:
        //SceneManager.getInstance().loadLevelThreeScene(engine);
            return true;
        case MENU_LFOUR:
        //SceneManager.getInstance().loadLevelFourScene(engine);
            return true;
        case MENU_LFIVE:
        //SceneManager.getInstance().loadLevelFiveScene(engine);
            return true;
        default:
            return false;
    }
}
}

Now go back to MainMenuScene class and navigate to Override method onMenuItemClicked, remove the comment from line SceneManager.getInstance().createLMenuScene();
The above code is similar to the MainMenuScene so I hope it does not need more explanations. run the project and see if you can see your level selector scene.

Create Main Menu Scene

* Creating Main Menu Scene

In this post I will be showing you how to create main menu scene. Follow the steps below,

1. First off all lets have a look at graphics below,
menuback.png
play.png
scores.png
> play button will navigate you to level selector scene
> scores button will navigate you to high score scene
2. Go to ResourcesManager class and define textures
    public ITextureRegion menu_background_region;
    public ITextureRegion play_region;
    public ITextureRegion scores_region;
    private BuildableBitmapTextureAtlas menuTextureAtlas;
Go to load menu graphics and put below code
private void loadMenuGraphics()
    {
    BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/menu/");
    menuTextureAtlas = new BuildableBitmapTextureAtlas(activity.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR);
    menu_background_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(menuTextureAtlas, activity, "menuback.png");
    play_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(menuTextureAtlas, activity, "play.png");
    scores_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(menuTextureAtlas, activity, "scores.png");
    try 
    {
       this.menuTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 0));
       this.menuTextureAtlas.load();
   
    catch (final TextureAtlasBuilderException e)
    {
           Debug.e(e);
    }
    }
We are done with loading assets.

3. Now lets create the new class called MainMenuScene as below,

package com.mindew.fruitecollector;

import org.andengine.audio.music.Music;
import org.andengine.entity.scene.menu.MenuScene;
import org.andengine.entity.scene.menu.MenuScene.IOnMenuItemClickListener;
import org.andengine.entity.scene.menu.item.IMenuItem;
import org.andengine.entity.scene.menu.item.SpriteMenuItem;
import org.andengine.entity.scene.menu.item.decorator.ScaleMenuItemDecorator;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.util.GLState;
import org.andengine.engine.camera.*;

import com.mindew.fruitecollector.SceneManager.SceneType;

public class MainMenuScene extends BaseScene implements IOnMenuItemClickListener {
private MenuScene menuChildScene;
private final int MENU_PLAY = 0;
private final int MENU_SCORES = 1;
GameActivity act;
@Override
public void createScene() {
// TODO Auto-generated method stub
createBackground();
createMenuChildScene();
}

@Override
public void onBackKeyPressed() {
// TODO Auto-generated method stub
System.exit(0);
}

@Override
public SceneType getSceneType() {
// TODO Auto-generated method stub
               //return the proper scene type
return SceneType.SCENE_MENU;
}

@Override
public void disposeScene() {
// TODO Auto-generated method stub
}
public void createBackground()
{
attachChild(new Sprite(0, 0, resourcesManager.menu_background_region, vbom)
   {
       @Override
       protected void preDraw(GLState pGLState, Camera pCamera) 
       {
           super.preDraw(pGLState, pCamera);
           pGLState.enableDither();
       }
   });
}
private void createMenuChildScene()
{
   menuChildScene = new MenuScene(camera);
   menuChildScene.setPosition(0, 0);
   
   final IMenuItem playMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_PLAY, resourcesManager.play_region, vbom), 1.2f, 1);
   final IMenuItem scoresMenuItem = new ScaleMenuItemDecorator(new SpriteMenuItem(MENU_SCORES, resourcesManager.scores_region, vbom), 1.2f, 1);
   
   menuChildScene.addMenuItem(playMenuItem);
   menuChildScene.addMenuItem(scoresMenuItem);
   
   menuChildScene.buildAnimations();
   menuChildScene.setBackgroundEnabled(false);
   
   playMenuItem.setPosition(playMenuItem.getX(), playMenuItem.getY() + 10);
   scoresMenuItem.setPosition(327, 380);
   
   menuChildScene.setOnMenuItemClickListener(this);
   
   setChildScene(menuChildScene);
}

@Override
public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
float pMenuItemLocalX, float pMenuItemLocalY) {
// TODO Auto-generated method stub
switch(pMenuItem.getID())
        {
        case MENU_PLAY:
        //SceneManager.getInstance().createLMenuScene();
            return true;
        case MENU_SCORES:
        //SceneManager.getInstance().createScoresScene();
            return true;
        default:
            return false;
    }
}

}

Explanations: In above code first we define the MenuChildScene called menuChildScene and then defined and initialized int variabled MENU_PLAY and MENU_SCORES.
Returned the scene type in method getSceneType().
Created background for our menu scene in method createBackground() and used it inside createScene().
Created menu child scene in method createMenuChildScene() and  used it inside createScene().

Run the project and see your game main menu.

Creating Splash Screen

We have crated all management classes, now we can start our actual game coding. First we are going to crate splash screen class which will display a splash screen and load resources at end.

Step 1: Loading splash resources.
I have used my company logo image as below,
> put your splash graphic file inside assets/gfx/ folder.
> call this file splash.png
> open the ResourcesManager class, and lets load this graphic. Create fields for the texture region, and splash texture.

public ITextureRegion splash_region;
private BitmapTextureAtlas splashTextureAtlas;

Load our splash file, inside the previously created loadSplashScreen() method.

BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
splashTextureAtlas = new BitmapTextureAtlas(activity.getTextureManager(), 256, 256, TextureOptions.BILINEAR);
splash_region = BitmapTextureAtlasTextureRegionFactory.createFromAsset(splashTextureAtlas, activity, "splash.png", 0, 0);
splashTextureAtlas.load();

Now lets prepare the method responsible for unloading our splash texture (which will be executed after completing the process of loading game resources and switching from the splash scene to the menu scene) Do it inside the previously created unloadSplashScreen()

splashTextureAtlas.unload();
splash_region = null;

Done, we've prepared the code responsible for loading/unloading splash resources, now lets move onto creating the splash scene.

Step 2: Creating the splash scene:

create a new class called SplashScene
as an extension, use the previously created abstract class BaseScene.
you will be forced by eclipse to add unimplemented methods (from our superclass)

package com.mindew.fruitecollector;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.util.GLState;

import com.mindew.fruitecollector.BaseScene;
import com.mindew.fruitecollector.SceneManager.SceneType;

/**
 * @author Mateusz Mysliwiec
 * @author www.matim-dev.com
 * @version 1.0
 */
public class SplashScene extends BaseScene
{
    @Override
    public void createScene()
    {

    }

    @Override
    public void onBackKeyPressed()
    {

    }

    @Override
    public SceneType getSceneType()
    {

    }

    @Override
    public void disposeScene()
    {

    }
}

Okay, we have handy and easy to understand methods, lets start with filling getSceneType(), simply return scene type (from the SceneManager`s enum)

@Override
public SceneType getSceneType()
{
    return SceneType.SCENE_SPLASH;
}

Now lets handle the scene creation, we will only need one sprite for our splash.
create a new field for our splash sprite:

private Sprite splash;

lets initialize this sprite, inside createScene() method:

splash = new Sprite(0, 0, resourcesManager.splash_region, vbom)
{
    @Override
    protected void preDraw(GLState pGLState, Camera pCamera)
    {
       super.preDraw(pGLState, pCamera);
       pGLState.enableDither();
    }
};
     
splash.setScale(1.5f);
splash.setPosition(400, 240);
attachChild(splash);

What we just did is initialize our splash sprite, and attached it in the middle of the screen. We also enabled dithering - to improve quality, since its gradient based art (see included link, for more information about dithering)

next step, handle disposing the scene, do it inside the disposeScene() method:

@Override
public void disposeScene()
{
    splash.detachSelf();
    splash.dispose();
    this.detachSelf();
    this.dispose();
}

This will dispose of the splash sprite, and detach it from the scene. Okay, our splash scene is done, now we just have to initialize it inside our activity, more below.

Step 3. Initializing our splash scene:

open our SceneManager class, lets create method responsible for initializing scene. In the parameter we will use OnCreateSceneCallback, because we will need it in the activity.

public void createSplashScene(OnCreateSceneCallback pOnCreateSceneCallback)
{
    ResourcesManager.getInstance().loadSplashScreen();
    splashScene = new SplashScene();
    currentScene = splashScene;
    pOnCreateSceneCallback.onCreateSceneFinished(splashScene);
}

We also will create method responsible for disposing splash scene (to dispose it when it will not be longer needed, which means after we successfully loaded menu resources)

private void disposeSplashScene()
{
    ResourcesManager.getInstance().unloadSplashScreen();
    splashScene.disposeScene();
    splashScene = null;
}

execute the createSplashScene() method inside onCreateScene in your Activity.

public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws IOException
{
    SceneManager.getInstance().createSplashScene(pOnCreateSceneCallback);
}

perform certain tasks while displaying splash (inside onPopulateScene in your Activity)

public void onPopulateScene(Scene pScene, OnPopulateSceneCallback pOnPopulateSceneCallback) throws IOException
{
    mEngine.registerUpdateHandler(new TimerHandler(2f, new ITimerCallback()
    {
            public void onTimePassed(final TimerHandler pTimerHandler)
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                // load menu resources, create menu scene
                // set menu scene using scene manager
                // disposeSplashScene();
                // READ NEXT ARTICLE FOR THIS PART.
            }
    }));
    pOnPopulateSceneCallback.onPopulateSceneFinished();
}

What it does:
It will display the splash screen until different tasks have been executed (Loading the menu resources, the menu scene and setting the scene to menu scene.)

At this step, after running our game, you should be able to see your splash scene being displayed (all the time, for now) In the next article, we will cover creating the menu scene and switching to it after loading it. Refer to the next part to continue.

Game Classes Setup - BaseScene & SceneManager

* Game Classes Setup - BaseScene & SceneManager

Scene management is very crucial part of game development, for this we gonna create two classes called BaseScene and SceneManager.

 BaseScene - This class will be a basic representation of each created scene in our game, it is an abstract class, which will handle basic scene logic.
SceneManager - This class will provide ways to manage our scenes, switching between them, keeping track of current scene, scene type etc.

1. BaseScene class:

package com.mindew.fruitecollector;

import org.andengine.engine.Engine;
import org.andengine.engine.camera.Camera;
import org.andengine.entity.scene.Scene;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import android.app.Activity;

import com.mindew.fruitcollector.ResourcesManager;
import com.mindew.fruitecollector.SceneManager.SceneType;

/**
 * @author Mateusz Mysliwiec
 * @author www.matim-dev.com
 * @version 1.0
 */
public abstract class BaseScene extends Scene
{
    //---------------------------------------------
    // VARIABLES
    //---------------------------------------------
   
    protected Engine engine;
    protected Activity activity;
    protected ResourcesManager resourcesManager;
    protected VertexBufferObjectManager vbom;
    protected Camera camera;
   
    //---------------------------------------------
    // CONSTRUCTOR
    //---------------------------------------------
   
    public BaseScene()
    {
        this.resourcesManager = ResourcesManager.getInstance();
        this.engine = resourcesManager.engine;
        this.activity = resourcesManager.activity;
        this.vbom = resourcesManager.vbom;
        this.camera = resourcesManager.camera;
        createScene();
    }
   
    //---------------------------------------------
    // ABSTRACTION
    //---------------------------------------------
   
    public abstract void createScene();
   
    public abstract void onBackKeyPressed();
   
    public abstract SceneType getSceneType();
   
    public abstract void disposeScene();
}

This is a core class for our every created scene in the game. It will be used as an extension, providing basic scene logic, using abstract methods. It will also have the most commonly used objects taken from previously created ResourcesManager. There is getSceneType , returning SceneType - it will be an enum inside the SceneManager class, ignore the error and move to the next step below to create the scene manager.

2. SceneManager class:

It will be a really important class in our game, responsible for switching between scenes and keeping track of the currently displayed scene. We will use SINGLETON HOLDER, which means we will be able to use this manger from the global level. It will also have an enum, containing our scene types. We also will create 4 BaseScene objects, for our scenes (splash, loading, menu and game scenes)

package com.mindew.fruitecollector;

import org.andengine.engine.Engine;

import com.mindew.fruitcollector.BaseScene;

/**
 * @author Mateusz Mysliwiec
 * @author www.matim-dev.com
 * @version 1.0
 */
public class SceneManager
{
    //---------------------------------------------
    // SCENES
    //---------------------------------------------
   
    private BaseScene splashScene;
    private BaseScene menuScene;
    private BaseScene gameScene;
    private BaseScene loadingScene;
   
    //---------------------------------------------
    // VARIABLES
    //---------------------------------------------
   
    private static final SceneManager INSTANCE = new SceneManager();
   
    private SceneType currentSceneType = SceneType.SCENE_SPLASH;
   
    private BaseScene currentScene;
   
    private Engine engine = ResourcesManager.getInstance().engine;
   
    public enum SceneType
    {
        SCENE_SPLASH,
        SCENE_MENU,
        SCENE_GAME,
        SCENE_LOADING,
    }
   
    //---------------------------------------------
    // CLASS LOGIC
    //---------------------------------------------
   
    public void setScene(BaseScene scene)
    {
        engine.setScene(scene);
        currentScene = scene;
        currentSceneType = scene.getSceneType();
    }
   
    public void setScene(SceneType sceneType)
    {
        switch (sceneType)
        {
            case SCENE_MENU:
                setScene(menuScene);
                break;
            case SCENE_GAME:
                setScene(gameScene);
                break;
            case SCENE_SPLASH:
                setScene(splashScene);
                break;
            case SCENE_LOADING:
                setScene(loadingScene);
                break;
            default:
                break;
        }
    }
   
    //---------------------------------------------
    // GETTERS AND SETTERS
    //---------------------------------------------
   
    public static SceneManager getInstance()
    {
        return INSTANCE;
    }
   
    public SceneType getCurrentSceneType()
    {
        return currentSceneType;
    }
   
    public BaseScene getCurrentScene()
    {
        return currentScene;
    }
}

We have our basescene and scene manager classes ready to use now.