Thursday, October 6, 2011

How to develop games on Android

One of the biggest markets in smart phones is games.  I am sure most of us would have played around with “Angry Birds” .  In this games tutorial you will learn different methods of developing  “Android Games”
At the end of the post is the video on how the code below works and the zip of all the source files used in this example.
Android Games can be developed in 3 ways
1)   Developing games using Android/Java libraries
2)   Developing games using External Libraries like OpenGL
3)   Developing games by porting existing c-game (pc game) to android.
Before getting started I assume that the reader is familiar with the basics of android programming like using activity, creating views, handling motion/touch events etc.
Also, apart from android sdk and eclipse some other tools are required for the game development. Details of the tools required, how to configure and use them will be explained as and when required. I will recommend to check out our last posts

Before starting with the game development lets understand the term “Main Loop”.

Main Loop:

Not just android any game written on any language consists of a set of custom views which are constantly refreshed/re-painted/re-drawn.  In some games we need to update the screen or re-draw the view elements at regular intervals.
E.g. consider two games (i) Android Snake Game (ii) Android Number Game for kids as shown.

In android snake game the snake has to move irrespective of the user input. Here the screen has to regularly re-drawn/re-painted to create the motion effect of the snake. Where as in the Number  game we need not redraw the screen now and then. The screen must be updated/re-drawn only when the user clicks/touches the screen.
So in the snake game we must re-draw the screen at regular intervals say 1sec in order to do that we make use of threads, while loops etc. and create a refresh/re-draw handler that updates screen regularly. This refresh/re-draw loop created is called “Main Loop”.
Note: It’s not that all games require Main Loop it depends on the game you are building.
In order to understand refresh handler we shall build a
“Ball Game” . In this game the user gets some points when ever he clicks on the ball, when the ball in the circle of the same color,  here I’m neither going to explain the score logic nor the UI events all that I’m going to focus on is the game view and refresh handler.


Before dicing into this code, I will recommend going through

Creating a Custom Widget in android

public class ballview extends View{
/* Refer to the above link for more information on using View class */
int width,height;
private Paint circlePaint,circlePaint1,circlePaint2,circlePaint3;
private Drawable[] mDrawable;
/* This will start your Refresh Handler  */
private RefreshHandler mRedrawHandler=new RefreshHandler();
private int[] posx,posy;
/* Create different constructors for your view class */
public ballview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initCalview();
}
/* Create different constructors for your view class */
public ballview(Context context, AttributeSet attrs) {
super(context, attrs);
initCalview();
}
/* Create different constructors for your view class */
public ballview(Context context) {
super(context);
initCalview();
}
Initialize all the variables. The image files can be downloaded from the zip file attached to the post.
Here the random function is used to select random position on the screen while the balls are falling down from the top

protected void initCalview()
{
mDrawable=new Drawable[4];
posx=new int[16];
posy=new int[16];
mDrawable[0] = this.getResources().getDrawable(R.drawable.bluen);
mDrawable[1] = this.getResources().getDrawable(R.drawable.greenn);
mDrawable[2] = this.getResources().getDrawable(R.drawable.redn);
mDrawable[3] = this.getResources().getDrawable(R.drawable.yellown);
for(int i=0;i<16;i++)
{
posx[i]=(int)(Math.random() * (250- 1 + 1) ) + 1;
posy[i]=(int)(Math.random() * (250 – 1 + 1) ) + 1;
}
}
More information on onMeasure method  can be found on Creating a Custom Widget in android
@Override
protected void onMeasure(int widthSpec, int heightSpec)
{
int specWidth=MeasureSpec.getSize(widthSpec);
int specHeight=MeasureSpec.getSize(heightSpec);
setMeasuredDimension(specWidth,specHeight);
set_pos();
}
public void set_pos()
{
int x;
int px=this.getMeasuredWidth();
int py=this.getMeasuredHeight();
width=(int)px;
height=(int)py;
this.layout(width/2, 0, 0, 0);
/* Initialize different paint objects to draw circles of different colors */
circlePaint=new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(Color.BLUE);
circlePaint.setStrokeWidth(1);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint1=new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint1.setStrokeWidth(1);
circlePaint1.setStyle(Paint.Style.STROKE);
circlePaint2=new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint2.setStrokeWidth(1);
circlePaint2.setStyle(Paint.Style.STROKE);
circlePaint3=new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint3.setStrokeWidth(1);
circlePaint3.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas)
{
int rad=Math.min(width/4, height/4);
/* Paint the circle objects on the canvas */
canvas.drawCircle(width/4,height/4, rad, circlePaint);
circlePaint1.setColor(Color.RED);
canvas.drawCircle(width-rad,height-rad, rad, circlePaint1);
circlePaint2.setColor(Color.YELLOW);
canvas.drawCircle(width-rad,height/4,rad/2, circlePaint2);
circlePaint3.setColor(Color.GREEN);
canvas.drawCircle(width/4,height-rad, rad/2, circlePaint3);
//int i=0;
for(int i=0;i<8;i++)
{
mDrawable[0].setBounds(posx[i],posy[i],posx[i]+35,posy[i]+35);
mDrawable[0].draw(canvas);
i++;
mDrawable[1].setBounds(posx[i],posy[i],posx[i]+35,posy[i]+35);
mDrawable[1].draw(canvas);
i++;
mDrawable[2].setBounds(posx[i],posy[i],posx[i]+35,posy[i]+35);
mDrawable[2].draw(canvas);
i++;
mDrawable[3].setBounds(posx[i],posy[i],posx[i]+35,posy[i]+35);
mDrawable[3].draw(canvas);
/* Refresh Handler re-draws the view and at this point waits/stops for a sec and after the
waiting period it again redraws the view and the process repeats.
Thus your screen gets updated regularly and you feel as if balls are falling from the top*/
mRedrawHandler.sleep(1000);
}
}
RefreshHandler class : This class updates the view every sec. It increments the Y-axis value and selects the
random X-axis position every second and repaints the screen this creates a feel as if  balls are falling from the top
class RefreshHandler extends Handler {
@Override
public void handleMessage(Message msg) {
for(int i=0;i<8;i++)
{
posy[i]=posy[i]+20;
posx[i]=(int)(Math.random() * (250- 1 + 1) ) + 1;
if(posy[i]<height)
{}
else
{posy[i]=0;}
}
ballview.this.invalidate();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};
}
/* Now Create an Activity and Display the View created above */
public class main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linear=new LinearLayout(this);
ballview ball= new ballview(this);
linear.addView(ball);
setContentView(linear);
}
}

No comments: