Wednesday, 6 February 2013

Android Game Development Tutorial ( Part1 )


Hi friends,
             Are you a game crazy? Do you want to develop your own game for Android OS?
So don’t suffer anymore, all the answers are here. I will be sharing with you my knowledge of game development for Android OS.

I will be completing this Android Game Development tutorial in 4 posts.
We will start from the basic of game development. Today we will learn how to create a basic game with basic game functionality. 

 Prerequisite are
1)    Basic knowledge of Core Java, Java Threads, Frames, Applets, Image, Event Handling.
2)    Net-beans.

First of all let’s discusses about the basic functionality of game.
1)    A main game object.
2)    Movement of the game object.   
3)    Background Scrolling.
4)    Handling of X and Y coordinate of your game object.


A main game object:-
            The main game object is the one from which the game player interacts directly. Take an example of a Mario game, Mario is the main game object.
            So first choose your game object, whichever you would like to see in your game.

            Movement of the game object:-
                        Then you should think of the movement of the game object. The basic movement are Jump, move downwards, move right, move left, stop.
                        According to your game need you can add or remove the features. Like fast running, high jump, crawl.
                       
            Background Scrolling:-
                        This is the important game functionality. Suppose you have a game screen of 500 x 250 (in pixels). You start the game and moving the game main object in the right direction. Here you have to decide how long you will go in right direction otherwise you will be out of the screen. So we have to fix the maximum X co-ordinate in right direction. Same thing apply on the left side movement, we have to fix the minimum X co-ordinate in left direction.
                        Then let’s see this, now you have fixed the minimum X and maximum X co-ordinate.
Suppose you are at the maximum X and you want to move further then how you will solve this situation.
Here comes Background Scrolling in picture. We will solve this situation via Background Scrolling. After a Maximum X we will not move the main game object but we will move the background of the game. If you do this the user will feel like game object is still moving.  The same thing we will apply when we reached the minimum X.
           
            Handling of X,Y co-ordinate:-
                        In game development so many things are depend on the handling of X,Y co-ordinates of the game objects.
                        You have to handle the co-ordinate whenever you are moving, jumping, etc.
                        Background Scrolling also is a trick of handling X,Y co-ordinates.

Now let’s create your first java game.

So what are the things you need for your first Game.
1)    GameMain.java                  (An applet class, This class handles Graphics and Event handling)
2)    HandlingXY.java                 (This class handles the X,Y co-ordinate of our Game)
3)    Image/1.png                        Image directory, 1.png is the first background image        
4)    Image/2.png                        Image directory, 2.png is the second background image
5)    Image/3.png                        Image directory,3.png is the third background image
6)  Image/gameHero.png         Image directory, gameHero.png is the fourth image

/**************************************************/
GameMain.java
/*****************************************************/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.applet.Applet;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;

/**
 *
 * @author Shobhit Upadhyaya
 */
public class GameMain extends Applet  implements Runnable, KeyListener{

    /**
     * Initialization method that will be called after the applet is loaded into
     * the browser.
     */
    
    static public int image3X=-1000;
    static public int image1X=0;
    static public int image2X=1000;

    private Image image, character, bg1, bg2, bg3;
    private Graphics gObject;
    private URL base;

    static public int bX=500;
    static public int bY=220;

    static int rX1=550;
    static int rX2=150;
    static int rY1=250;
    static int rY2=50;
    HandlingXY mainObject;
        
    public void init() {
        // TODO start asynchronous download of heavy resources
        
        setSize(900, 400);
  setBackground(Color.WHITE);
  setFocusable(true);
  addKeyListener(this);
  Frame frame = (Frame) this.getParent().getParent();
  frame.setTitle("Game Development [Part1]");
  try {
   base = getCodeBase();
  } catch (Exception e) {
   // TODO: handle exception
  }

  // Image Setups
  character = getImage(base, "images/gameHero.png");
        bg1 = getImage(base, "images/1.png");
                bg2 = getImage(base, "images/2.png");
                bg3 = getImage(base, "images/3.png");

    }
    
    @Override
 public void start() {
  mainObject = new HandlingXY();
  Thread thread = new Thread(this);
  thread.start();
 }

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

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

 @Override
 public void run() {
  while (true) {
   mainObject.updateXY();
                        
   repaint();
   try {
    Thread.sleep(17);
   } catch (InterruptedException e) {
    //e.printStackTrace();
   }
  }
 }

 @Override
 public void update(Graphics g) {
            
            
  if (image == null) {
   image = createImage(this.getWidth(), this.getHeight());
   gObject = image.getGraphics();
  }

  
  paint(gObject);

  g.drawImage(image, 0, 0, this);

 }

 @Override
 public void paint(Graphics g) {
            
                g.drawImage(bg1, image3X, 0, this);
                g.drawImage(bg2, image1X, 0, this);
                g.drawImage(bg3, image2X, 0, this);         
  g.drawImage(character, mainObject.getCenterX(), mainObject.getCenterY() , this);

 }

 @Override
 public void keyPressed(KeyEvent e) {

  switch (e.getKeyCode()) {
  case KeyEvent.VK_UP:
   System.out.println("Move up");
   break;

  case KeyEvent.VK_DOWN:
   System.out.println("Move down");
   break;

  case KeyEvent.VK_LEFT:
   mainObject.moveLeft();
   break;

  case KeyEvent.VK_RIGHT:
   mainObject.moveRight();
   break;

  case KeyEvent.VK_SPACE:
   System.out.println("Jump");
   mainObject.jump();
   break;

  }

 }

 @Override
 public void keyReleased(KeyEvent e) {
  switch (e.getKeyCode()) {
  case KeyEvent.VK_UP:
   System.out.println("Stop moving up");
   break;

  case KeyEvent.VK_DOWN:
   System.out.println("Stop moving down");
   break;

  case KeyEvent.VK_LEFT:
   mainObject.stop();
   break;

  case KeyEvent.VK_RIGHT:
   mainObject.stop();
   break;

  case KeyEvent.VK_SPACE:
   System.out.println("Stop jumping");
   break;

  }

 }

 @Override
 public void keyTyped(KeyEvent e) {
  // TODO Auto-generated method stub

 }
    // TODO overwrite start(), stop() and destroy() methods
}




Let’s understand main code snippets of GameMain Class one by one.
1)    public class GameMain extends Applet  implements Runnable, KeyListener

We are using the Runnable and KeyListener Class to handle threads and Key Events.

2)    getCodeBase();

We are using the getCodeBase() to get the base URL.  It provides the URL for the location of the applet's class file.
getImage(base, "images/gameHero.png");
here base is the object of the URL class;
URL base = getCodeBase();
To load an image in an applet, we are use the getImage() function.

3)    Start() function of the applet

public void start() {
            mainObject = new HandlingXY();
            Thread thread = new Thread(this);
            thread.start();
}
Here we are creating the object of the HandlingXY class.
We are also creating a new Thread and we are starting the thread also.

4)    Run() of the Thread

Here we are keep on calling the updateXY()  and repaint() function.
updateXY() updates the X,Y co-ordinates and repaint() is for drawing the background and game object images on the applet.

Repaint() => update() => paint()

5)    Key Event Handling.

KeyPressed() and KeyReleased() and keyTyped() these function we are using for key handling.           



/********************************************************/
HandlingXY.java
/********************************************************/


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Shobhit Upadhyaya
 */
public class HandlingXY {
    
    private final int Y = 250;
    private int centerX = 100;
    private int centerY = Y;
    private boolean jumped = false;
    private int speedX = 0;
    private int speedY = 1;
    
    private void handlingY()
    {
        // Updates Y Position
        centerY += speedY;

        if (centerY + speedY >= Y) {
                centerY = Y;
  
        }

        // Handles Jumping
        if (jumped == true) {
                speedY += 1;


                if (centerY + speedY >= Y ) {
                        centerY = Y;
                        speedY = 0;
                        System.out.println("Jump done...");
                        jumped = false;
                }

        }
    }
    
    private void handlingX()
    {
    // Here we are fixing the minimum X coordinate of mainObject. 
        if (centerX + speedX <= 160) {   
                centerX = 161;
        }
        if (speedX < 0) {   

                centerX += speedX;

                /*
                 * Handling Background Scrolling
                 * Putting 3 images back to back.
                 * 
                 */
                GameMain.image3X -= speedX;
                GameMain.image1X -= speedX;
                GameMain.image2X -= speedX;

                if(GameMain.image1X >= 1000)
                {
                    GameMain.image1X -= 3000;

                }
                if(GameMain.image3X >= 1000)
                {
                    GameMain.image3X -= 3000;

                }
                if(GameMain.image2X >= 1000)
                {
                    GameMain.image2X -= 3000;

                }


        }
        else if (speedX == 0) {   
                /*
                 Speed zero, when u don;t press any key
                 */
             }
        
        else {
                if (centerX <= 400) {   // 400 is the max X point 
                        centerX += speedX;
                } 
                else 
                {
                        
                     /*
                     * Handling Background Scrolling
                     * Putting 3 images back to back.
                     * 
                     */

                    GameMain.image3X -= speedX;
                    GameMain.image2X -= speedX;
                    GameMain.image1X -= speedX;

                    if(GameMain.image1X <= -1000)
                    {
                        GameMain.image1X += 3000; // 1000 * no of images = 3000
                    }
                    if(GameMain.image2X <= -1000)
                    {
                        GameMain.image2X += 3000;
                    }
                    if(GameMain.image3X <= -1000)
                    {
                        GameMain.image3X += 3000;
                    }

                }
        }
    }
   
    public void updateXY(){

        handlingX();
        handlingY();
        
 }

       
 public void moveRight() {
  speedX = 10;    // how much pixel object moves to right per -> key pressed
 }

 public void moveLeft() {
  speedX = -10;
 }

 public void stop() {
  speedX = 0;
 }

 public void jump() {
  if (jumped == false) {
   speedY = -20;   
   jumped = true;
  }

 }
 public int getCenterX() {
  return centerX;
 }

 public int getCenterY() {
  return centerY;
 }

}

Let’s understand main code snippets of HandlingXY Class:-

1)    UpdateXY() :-
This is the main function of this class. This function deals with the X,Y co-ordinate of the game.
This calls two functions.
handlingX();             This handles the X co-ordinate, when you move right or left and Background Scrolling.

handlingY();             This handles the Y co-ordinate , when you perform jump.

2)    Let’s see how we are handling Background Scrolling when you reach the minimum X
/*
                 * Handling Background Scrolling
                 * Putting 3 images back to back.
                 *
                 */


GameMain.image3X -= speedX;                       
               GameMain.image1X -= speedX;
               GameMain.image2X -= speedX;
                 
                  Here speedX is the speed of the character when the character is moving in the left direction.
     
      Image3 X1= -1000;                       
      Image3X2= 0;

      Image1X1=0;
      Image1X2=1000;

      Image2X1=1000;
      Image2X2=2000;

       X1 is the position from where we are starting the image drawing. X2 is the position where the image drawing ends. 
      How we are calculating the X2, we know the X1 (from where we are starting the image) and add the number of pixels you have in you image. Here all the images are 1000 pixels long.

      Our applet screen starting X is 0 and max is 500. So in the starting we will only see the Image1 because when we are drawing the image we are setting the start coordinate of this image 0 (X1) and 1000(X2).


Image3
Image1
Image2
                                      ^
                                       |
                           Our character



When we do background scrolling we subtract the X position of the image with the speedX.
Suppose the current X position of the image is 0 and speedX is -10, after doing the subtraction you will get new X is 10.
speedX is –ve negative when you move left. speedX is +ve positive when you move right.

Like that Image3 X1 alse get updated. Now it became -990 and X2 = X1 + 1000 = 10;
Now here the small part of the Image3 comes into the game screen ( 10 pixel long ). 
Did you get now how the hidden Image3 came into the screen ?

Image3
Image1
Image2
                               ^
                              |
            Our character
               

What will happen when you reach the X1=0 of the Image3. Because we don’t have anyother image behind Image3. You will get the blank screen. To handle this situation you need to keep on putting the right hand side image back to the last left hand side image.

                if(GameMain.image1X >= 1000)
                {
                    GameMain.image1X -= 3000;

                }
                if(GameMain.image3X >= 1000)
                {
                    GameMain.image3X -= 3000;

                }
                if(GameMain.image2X >= 1000)
                {
                    GameMain.image2X -= 3000;

                }


/************************************************************
gameHero.png
/************************************************************



/************************************************************
1.png
/************************************************************


/************************************************************/
2.png
/************************************************************/


/***************************************************/
3.png
/**************************************************/




Steps to be followed to create a our first game project, are :-
1)    Open NetBeans
2)    File --> New Project -->  select Java Application , click Next
3)    In the project name give "GameDevelopmentPart1" and do not create the Main Class, because we will be using an Applet. So unchecked the Create Main Class check-box  and Click Finish.
4)    Create an applet class. Right hand side of the Projects window, right click on the GameDevelompentPart1 project, select new --> choose Applet.
5)    Give the applet name GameMain.java 
6)    Create an another class. Right click on the GameDevelopmentPart1 project, select new  --> choose Java Class.
7)    Give the Java Class name HandlingXY.java
8)    Create a directory named as images in the src folder of the GameDevelopmentPart1 project.
9)    Copy all the images what i have shared with you in the images folder and mentioned the same name what i have given.
10)   Copy the source code of the GameMain.java and HandlingXY.java with the code i have shared with you and paste it in the respective file of the same name what you have created.
11)    Click on the GameMain.java and press SHIFT+F6 to run the applet.



I hope you will enjoy your own first game.

What we will learn in part2 of game development ?
1)  We will create a game level.
2)  We will add animation in the game.
3)  We will learn how to resolve collision detection.
4)  We will add game over, game wining scenario.

This tutorial is useful for anyone who is interested to learn game development for Android OS. If you are a CS or IT student you can create a Android game project, install it on your Android phone and give the demo of the project.
If you are a IT professional you can develop your own game and you can put your game in the Android market for other users.
Its all upto you how you want to cash your knowledge.

At last i want to say is, I am not a java professional. I am a C & Linux Developer. If i can learn this "you can too". 

Please do comments if you have any doubt related to today's topic.
Please share this blog with your friends, college mates or colleague so that they can also learn.





                                                                                 
Thanks and Cheers,
Happy Learning ...........