Click here to Skip to main content
11,481,265 members (60,906 online)
Click here to Skip to main content

Simple Android Ball Game

, 29 Apr 2011 CPOL 292.1K 50.4K 70
Rate this:
Please Sign up or sign in to vote.
Tutorial about creating a nice ball game for Android using AndEngine

Introduction

This is a tutorial for developing a Ball Game in Android OS. It will introduce you to developing Android games using AndEngine (free Android 2D open source game engine). To understand this tutorial, you will need to have some basic knowledge about AndEngine and programming in Java. If you don't have knowledge about AndEngine, you should check this link. The goal of this tutorial is to teach you how to make your own Android game.

The Game

It's a classic game idea implemented in a modern way. You control the ball using the accelerometer sensor and your goal is to collect all "diamonds", avoid enemy balls and to come safely to the end.

pic1.jpg

pic2.jpg

pic3.jpg

pic4.jpg

What You Need to Start?

To start developing your own Android games, you need SDK and game engine (it will make your life way easier!). I used Eclipse SDK and game engine called AndEngine. Are you wondering how to setup Eclipse SDK and AndEngine together? Click on the link to see "Getting started with AndEngine" tutorial.

Let's Do Some Coding!

Let's see what is hiding in the code! Please note that I didn't paste the full source code here. I just pasted some snippets. You can download the full project to see the complete source code.

First, we will take a short tour in the main class.

public class GameLogicController extends BaseGameActivity 
	implements IAccelerometerListener{
                 public PlayerProfileManager playerProfileManager; 
                 public LevelController levelController;
                 private Camera camera;
                 protected PhysicsWorld mPhysicsWorld;
                 public Texture mTexture;
                 public TextureRegion enemyTextureRegion;
                 private float mGravityX;
                 private float mGravityY;
                 private final Vector2 mTempVector = new Vector2();
                 public TiledTextureRegion mCircleFaceTextureRegion;
                 private RepeatingSpriteBackground mGrassBackground;
                 private Sound mGameOverSound;
                 ...
}

GameLogicController is the base class in our game, BaseGameActivity is the base class in AndEngine and IAccelerometerListener is the interface used to get data from your mobile phone accelerometer sensor. PlayerProfileManager and LevelController are just some game classes that you will know later.

@Override
public Engine onLoadEngine() {
	...

	levelController.mCameraWidth = 460;
	levelController.mCameraHeight = 320;
	camera = new Camera(0, 0, levelController.mCameraWidth, 
			levelController.mCameraHeight);
	return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, 
	new RatioResolutionPolicy(levelController.mCameraWidth, 
	levelController.mCameraHeight), camera).setNeedsSound(true));  
}

Method onLoadEngine creates a new game engine. First, we need to create Camera for declaring the screen resolution. An important and very useful thing is that Camera resolution isn't connected with mobile phone resolution. That will save you really a lot of work with graphics positions! For example, we declared screen resolution 460x320. You don't need to take care about mobile phone resolution, because you will always use AndEngine resolution (460x320) and AndEngine will automatically recalculate AndEngine resolution to real mobile phone resolution. The next step is to create new Engine. You just need to declare screen orientation (landscape or portrait), screen resolution and custom options. We used only one custom option, for enabling sound.

public Scene newGameLevelScene(int levelId){
	Scene scene = new Scene(2);
	this.mPhysicsWorld = new FixedStepPhysicsWorld(60, new Vector2(0, 0), false);
	levelController.setScene(scene);
	levelController.setmPhysicsWorld(mPhysicsWorld);
	levelController.createFrame();
	levelController.loadLevel(levelId);
	this.enableAccelerometerSensor(this);
	scene.registerUpdateHandler(this.mPhysicsWorld);
	return scene;
}

Here, you can see four very important things. First, we need to create a new display Scene and FixedStepPhysicWorld. FixedStepPhysicWorld is a 2D simulation of real world physic model. It's used for calculating gravity, collision detection... Let's focus on PhysicWorld. It takes three parameters. The first one is frames per seconds (how many times per second should screen be refreshed), the second is gravity vector and third is just if we want to allow PhysicWorld sleeping. At the end, we need to set enableAccelerometerSensor and registerUpdateHandler.

@Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
		this.mGravityX = pAccelerometerData.getY() * 2;
		this.mGravityY = pAccelerometerData.getX() * 2;
		if(this.mGravityX > con)
			this.mGravityX = con;
		if(this.mGravityY > con)
			this.mGravityY = con;
		if(this.mGravityX < con * (-1))
			this.mGravityX = con * (-1);
		if(this.mGravityY < con * (-1))
			this.mGravityY = con * (-1);
		this.mTempVector.set(this.mGravityX, this.mGravityY);
		this.mPhysicsWorld.setGravity(this.mTempVector);
	}

In method newGameScene, we enabled accelometerSensor that controls method onAccelerometerChanged. This method is called whenever accelerometer is changed.

protected Scene createQuitScene() {
		
	Scene scene = new Scene(2);
	scene.setBackground(this.mMenuBackground);
	Sprite buttonLevel = new Sprite(100, 100, 250, 70, this.mMenuOkTextureRegion)
	{
		@Override
		public boolean onAreaTouched
		(TouchEvent pSceneTouchEvent,float pTouchAreaLocalX, 
		float pTouchAreaLocalY)
		{
			if(checkTouchTime())
				GameLogicController.getInstance().finish();
			
			return true;
		}
	};
		
	scene.registerTouchArea(buttonLevel);
	scene.getTopLayer().addEntity(buttonLevel);
	...
} 

Sprite is just graphic on the scene. Much more interesting is the method onAreaTouched. It is callback and whenever someone will press on the button (sprite), this method will be called. Don't forget to register touch area (registerTouchArea) and to add button (addEntity) to the scene!

We just finished with the main class, so we can move to the LevelController class.

public class LevelController   {
        private ArrayList<Shape> enemyList;
	private ArrayList<Shape> goodsList;
	private ArrayList<Shape> endPointList;
        ...

public void createPlayer(TiledTextureRegion mCircleFaceTextureRegion, int x, int y){
	//mPlayer = new Player(x, y, mCameraHeight/10,mCameraHeight/10,
	mCircleFaceTextureRegion, this);
	mPlayer = new Player(x, y, 30,30,mCircleFaceTextureRegion, this);
	FixtureDef FIXTURE = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
	Body body;
	body = PhysicsFactory.createCircleBody(mPhysicsWorld, mPlayer, 
	BodyType.DynamicBody, FIXTURE);
	
	mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector
	(mPlayer, body, true, true, false, false));
	scene.getTopLayer().addEntity(mPlayer);		
     }
...
}

LevelController class is responsible for loading levels and controlling level events. Arraylists enemyList, goodsList and endPointList are used for storing enemy balls, goods (diamonds) and end points (finish line). Method createPlayer creates a new player on position x,y with size 30x30, PhysicFactory.CreateFixtureDef creates a new physical object. Physical object should be registered to mPhysicsWorld for collision detection.

public void callbackCollisionGoods(int i){
		Shape goodShape = goodsList.get(i);
		scene.getBottomLayer().removeEntity(goodShape);
		goodsList.remove(i);
	}

If player collects diamond, callbackCollisionGoods is called. In this method, we remove diamond from goodsList and goodShape from scene.

Other methods in this class are very similar and I won't describe them in detail.

The next class is PlayerProfileManager. In this class, you will find only basic Java code except method WriteSettings.

private void WriteSettings() {
	String FILENAME = "settings2";
	FileOutputStream fos = null;
	DataOutputStream dos;

	try {
		fos = gameLogicController.openFileOutput(FILENAME, Context.MODE_PRIVATE);
	} catch (FileNotFoundException e) {			
	}
	try {
		dos=new DataOutputStream(fos);
		
		dos.writeInt(unlockedLevelId);	
	} catch (IOException e) {
	}
	try {
		fos.close();
	} catch (IOException e) {
	}
}

In method WriteSettings, we save level information to mobile phone. It's necessary to open, write and close file. Actually, we save only one number - ID of last unlocked level. For example, if level ID is 5, then levels 1, 2, 3, 4 and 5 are unlocked.

The last described class is Player.

public class Player extends AnimatedSprite   {
...
@Override
	protected void onManagedUpdate(final float pSecondsElapsed) {
		super.onManagedUpdate(pSecondsElapsed);
		onBeforePositionChanged();
	}

private boolean onBeforePositionChanged(){
		
	//speed up
	if(frameCount < 2){
		frameCount++;
		return true;
	}
	frameCount = 0;
		
	int enemyListSize = levelController.getEnemyList().size();
	for(int i = 0; i < enemyListSize; i++)
		if(this.collidesWith(levelController.getEnemyList().get(i)))
		{
			levelController.callbackCollisionEnemy();
			return false;
		}
	for(int i = 0; i < levelController.getGoodsList().size(); i++)
		if(this.collidesWith(levelController.getGoodsList().get(i)))
		{
			levelController.callbackCollisionGoods(i);
			return false;
		}

	for(int i = 0; i < levelController.getEndPointList().size(); i++)
		if(this.collidesWith(levelController.getEndPointList().get(i)))
		{
			levelController.callbackCollisionWithEndPoint();
			return false;
		}
	return true;
    }
...
} 

Player class is extended AnimatedSprite. The difference between Sprite and AnimatedSprite is just one - animated sprite consists of more pictures (animation) while Sprite consist of one picture. OnManagedUpdate is callback executed every "x" miliseconds. OnBeforePositionChanged checks if player is in collision with enemy, diamond or end point. If it's in collision, then the appropriate callback is executed.

Android Game Developing

I hope you see that Android game developing isn't too hard. With some practice, you can develop your Android dream game. At the end of the tutorial, I would like to thank you for your attention. This is my first article and I would be really glad if you give me any feedback.

History

  • 29 April, 2011- Article uploaded

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sašo Mađarić

Slovenia Slovenia
I'm Sašo Mađarić, student in master course of the computer scient in university FERI Maribor, Slovenia. I have knowledge programming languages like C, C++, Java, C#, Adobe Flash/Flex, Objective C 2.0, js,... I have couple of years experiences with developing software for some slovenian companies, but i also worked in private university PUC Minas Gerais located in Belo Horizonte, Brazil. I'm interested in many areas, like artificial intelligence, image processing, development of computer games, information systems... For more informations please contact me by email.

http://www.linkedin.com/pub/saso-madaric/72/372/b1a

Comments and Discussions

 
Bugraj Pin
Member 1076283514-Jan-15 3:06
memberMember 1076283514-Jan-15 3:06 
QuestionCrashes after start a level Pin
Member 1133895228-Dec-14 0:43
memberMember 1133895228-Dec-14 0:43 
Questiondoes not compile, the following error, only works on the android 1.6 or higher also, help me please Pin
Jose Gomes11-Sep-14 8:51
memberJose Gomes11-Sep-14 8:51 
QuestionNice tutorial Pin
Member 1075870626-Jun-14 5:12
memberMember 1075870626-Jun-14 5:12 
QuestionError (Couldn't load andenginephysicsbox2dextension) findLibrary returned null Pin
Member 1070223928-Mar-14 2:49
memberMember 1070223928-Mar-14 2:49 
QuestionError Pin
Member 105812118-Feb-14 6:03
memberMember 105812118-Feb-14 6:03 
GeneralGreat article Pin
_dEvElOpEr_30-Jan-14 1:09
member_dEvElOpEr_30-Jan-14 1:09 
Questionerror Pin
Member 103804924-Nov-13 20:33
memberMember 103804924-Nov-13 20:33 
Questionerror Pin
Member 1024789317-Sep-13 7:02
memberMember 1024789317-Sep-13 7:02 
AnswerRe: error Pin
Member 109205105-Jul-14 8:45
memberMember 109205105-Jul-14 8:45 
QuestionHello Pin
Member 102598598-Sep-13 2:37
memberMember 102598598-Sep-13 2:37 
AnswerRe: Hello Pin
Sašo Mađarić8-Sep-13 2:56
memberSašo Mađarić8-Sep-13 2:56 
QuestionApp crashes on Emulator version 1.6 too! Pin
memberash24-Jul-13 10:27
membermemberash24-Jul-13 10:27 
AnswerRe: App crashes on Emulator version 1.6 too! Pin
Sašo Mađarić4-Sep-13 3:24
memberSašo Mađarić4-Sep-13 3:24 
QuestionRe: App crashes on Emulator version 1.6 too! Pin
Member 106467485-Mar-14 21:15
memberMember 106467485-Mar-14 21:15 
QuestionThe application crashes. Which version I should use? Pin
FAVIO0071-Jul-13 11:59
memberFAVIO0071-Jul-13 11:59 
QuestionUnfortunately, The Hardest Game has stopped Pin
Joehamir Balabadan20-Jun-13 19:17
memberJoehamir Balabadan20-Jun-13 19:17 
AnswerRe: Unfortunately, The Hardest Game has stopped Pin
Sašo Mađarić1-Jul-13 19:58
memberSašo Mađarić1-Jul-13 19:58 
GeneralMy vote of 5 Pin
VitorHugoGarcia17-Jun-13 7:14
memberVitorHugoGarcia17-Jun-13 7:14 
GeneralRe: My vote of 5 Pin
Sašo Mađarić17-Jun-13 9:01
memberSašo Mađarić17-Jun-13 9:01 
QuestionCrashing Pin
dangalg28-May-13 2:04
memberdangalg28-May-13 2:04 
AnswerRe: Crashing Pin
Sašo Mađarić17-Jun-13 9:02
memberSašo Mađarić17-Jun-13 9:02 
GeneralRe: Crashing Pin
Member 1022300826-Aug-13 22:33
memberMember 1022300826-Aug-13 22:33 
GeneralRe: Crashing Pin
james0071113-Mar-14 20:24
memberjames0071113-Mar-14 20:24 
GeneralMy vote of 5 Pin
Member 1006347219-May-13 13:17
memberMember 1006347219-May-13 13:17 
GeneralRe: My vote of 5 Pin
Sašo Mađarić17-Jun-13 9:01
memberSašo Mađarić17-Jun-13 9:01 
Questionmultiple sliding window i n one activity Pin
Sanjay22Tomar18-Apr-13 1:51
memberSanjay22Tomar18-Apr-13 1:51 
AnswerRe: multiple sliding window i n one activity Pin
sujeet878818-Apr-13 1:53
membersujeet878818-Apr-13 1:53 
GeneralRe: multiple sliding window i n one activity Pin
Sanjay22Tomar18-Apr-13 1:53
memberSanjay22Tomar18-Apr-13 1:53 
AnswerRe: multiple sliding window i n one activity Pin
sujeet878818-Apr-13 1:54
membersujeet878818-Apr-13 1:54 
GeneralMy vote of 5 Pin
mlkhedekar851-Apr-13 20:50
membermlkhedekar851-Apr-13 20:50 
QuestionChange Background Color Pin
M Rizal Hakim20-Mar-13 22:25
memberM Rizal Hakim20-Mar-13 22:25 
AnswerRe: Change Background Color Pin
Sašo Mađarić25-May-13 5:22
memberSašo Mađarić25-May-13 5:22 
QuestionSoundManager Pin
Roystonton19-Feb-13 14:24
memberRoystonton19-Feb-13 14:24 
AnswerRe: SoundManager Pin
Sašo Mađarić20-Feb-13 6:50
memberSašo Mađarić20-Feb-13 6:50 
GeneralRe: SoundManager Pin
haydarhaydar28-Mar-13 5:45
memberhaydarhaydar28-Mar-13 5:45 
GeneralRe: SoundManager Pin
Sašo Mađarić25-May-13 5:22
memberSašo Mađarić25-May-13 5:22 
QuestionIMAGES AND DRAWABLES Pin
Roystonton19-Feb-13 14:06
memberRoystonton19-Feb-13 14:06 
AnswerRe: IMAGES AND DRAWABLES Pin
Sašo Mađarić20-Feb-13 7:00
memberSašo Mađarić20-Feb-13 7:00 
QuestionError game stops unexpectedly Pin
Tanveer Ali 865-Feb-13 6:27
memberTanveer Ali 865-Feb-13 6:27 
AnswerRe: Error game stops unexpectedly Pin
Sašo Mađarić20-Feb-13 7:01
memberSašo Mađarić20-Feb-13 7:01 
QuestionCrashing Pin
sapramit29-Jan-13 23:20
membersapramit29-Jan-13 23:20 
AnswerRe: Crashing Pin
Sašo Mađarić20-Feb-13 7:02
memberSašo Mađarić20-Feb-13 7:02 
GeneralRe: Crashing Pin
Member 998455115-Apr-13 6:26
memberMember 998455115-Apr-13 6:26 
GeneralMy vote of 5 Pin
kaveribc23-Jan-13 22:45
memberkaveribc23-Jan-13 22:45 
GeneralRe: My vote of 5 Pin
Sašo Mađarić20-Feb-13 7:02
memberSašo Mađarić20-Feb-13 7:02 
Questionthanks Pin
kamalakarreddy115-Jan-13 0:43
memberkamalakarreddy115-Jan-13 0:43 
QuestionI can't control the Ball in the Simple Android Ball Game? Pin
nguyen tuan van30-Dec-12 1:01
membernguyen tuan van30-Dec-12 1:01 
AnswerRe: I can't control the Ball in the Simple Android Ball Game? Pin
Sašo Mađarić28-Feb-13 11:43
memberSašo Mađarić28-Feb-13 11:43 
QuestionMethod chechTouchTime(). Pin
nghelam200816-Nov-12 19:18
membernghelam200816-Nov-12 19:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 29 Apr 2011
Article Copyright 2011 by Sašo Mađarić
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid