Posted by Talha Suleman : Talha Suleman Wednesday 28 May 2014


5 Steps to Android Game Development


1. Download The Android Game Framework

In Days 5 and 6, we have developed the Android Game Framework that we will build our game on top of.
If you do not have this framework handy (or are having issues with it), here is the full Project you can download and import into Eclipse.

Download the license:
http://www.apache.org/licenses/LICENSE-2.0.txt

Source Code

kiloboltandroidframework.zip
Download File

2. CHANGE THE NAME OF THE PACKAGES

Picture
I. Right click on each of the two packages:

1. com.kilobolt.framework
2. com.kilobolt.framework.implementation

Select Refactor >> Rename.
Change kilobolt to a name of your choice.

II. You will also want to create a new package in the src folder.
Call it: com.yourcompany.yourgame.

You can also change the name of the Project for organization.
To recap what we have discussed in Day 5, our Android game's architecture will consist of:

1. The interface (com.kilobolt.framework)
2. The implementation of the interface (com.kilobolt.framework.implementation)
3. The game code (com.yourcompany.yourgame)

All of the classes that go into making your game will go into the 3rd package; however, you cannot directly port a Java game to Android. For example, Java's Swing class is not supported in Android, so you will not be able to use its methods (you would have to use methods that we implemented in package #2). This means you will be rewriting some of the code.

3. Develop the Game


In the newly created package, we can create our game. With a few changes, we can bring in most of the code from Units 2 and 3. If you are creating a game from scratch, you would just follow the following structure to create the fitting classes.

How will this game be structured?Our game will have just one Activity (recall Activities are windows) that will display a SurfaceView (that we create using the AndroidFastRenderViewclass). This SurfaceView will paint objects (created using classes like Robot or Platform) as they update.

How do we go about doing this? Assuming that we are creating a game called Sample:

1. Create a SampleGame class in the 3rd package. Extend AndroidGame.

Since AndroidGame implements the Game class from the framework you typically would have to implement all the methods from the Game class insideAndroidGame. However, since AndroidGame is an abstract class, you can choose not to implement certain methods. However, you would be required to implement these methods in any subclass that extends AndroidGame (in this case SampleGame).

So our SampleGame might look something like this:

1. SampleGame class (sample code)
package com.kilobolt.samplegame;

import com.kilobolt.framework.Screen;
import com.kilobolt.framework.implementation.AndroidGame;

public class SampleGame extends AndroidGame {
    @Override
    public Screen getInitScreen() {
        return new LoadingScreen(this);
    }
 
}
We would make SampleGame the main Activity of our game (we will do so in the AndroidManifest in step 4). That way, when we start the game, the SampleGame class will be instantiated, and the methods from the Activity Lifecycle will be called (starting with the onCreate). These methods are all implemented in the AndroidGame superclass that SampleGame extends.

You will find that we set most of the screen layouts in the onCreate method of the AndroidGame class. You can change the screen resolution of the game in there by editing these four numbers:

int frameBufferWidth = isPortrait ? 8001280;
int frameBufferHeight = isPortrait ? 1280800;

As it is, this would create a 1280x800 canvas for our game. This canvas will shrink or stretch to fit any device.

To add the back button functionality, add the following code:

@Override
public void onBackPressed() {
getCurrentScreen().backButton();
}



Notice that the getInitScreen() has the following statement:
return new LoadingScreen(this);


This would transition into the LoadingScreen class, which we will define soon:

2. Assets class (sample code)
package com.kilobolt.samplegame;

import com.kilobolt.framework.Image;
import com.kilobolt.framework.Sound;

public class Assets {
 
    public static Image menu;
    public static Sound click;
}
This Assets class is used to create a variable for each resource that we will use in the game. Notice that these variables menu and click are not initialized. We will initialize them in the LoadingScreen below:

3. LoadingScreen class (sample code)
package com.kilobolt.samplegame;


import com.kilobolt.framework.Game;
import com.kilobolt.framework.Graphics;
import com.kilobolt.framework.Screen;
import com.kilobolt.framework.Graphics.ImageFormat;


public class LoadingScreen extends Screen {
    public LoadingScreen(Game game) {
        super(game);
    }


    @Override
    public void update(float deltaTime) {
        Graphics g = game.getGraphics();
        Assets.menu = g.newImage("menu.jpg", ImageFormat.RGB565);
        Assets.click = game.getAudio().createSound("explode.ogg");


     
        game.setScreen(new MainMenuScreen(game));


    }


    @Override
    public void paint(float deltaTime) {


    }


    @Override
    public void pause() {


    }


    @Override
    public void resume() {


    }


    @Override
    public void dispose() {


    }


    @Override
    public void backButton() {


    }
}
All screen classes have three important classes. The update() method, and the paint() method, and the backButton() method (which is called when the user presses the back button in the game).

In the update() method, you load all the resources that you will use in the game (i.e. all the resources that we have created in the Assets class). We would not need anything in our paint() method, unless you would like to have an image while the game loads these resources (make sure you load this in another class).

The files used in this example: menu.jpg, explode.ogg must be placed in the assets folder of our project.

When all the Assets are loaded, we call the statement: game.setScreen(new MainMenuScreen(game));


This opens the MainMenuScreen, which we define below:

4. MainMenuScreen class (sample code)

package com.kilobolt.samplegame;

import java.util.List;

import com.kilobolt.framework.Game;
import com.kilobolt.framework.Graphics;
import com.kilobolt.framework.Screen;
import com.kilobolt.framework.Input.TouchEvent;


public class MainMenuScreen extends Screen {
    public MainMenuScreen(Game game) {
        super(game);
    }


    @Override
    public void update(float deltaTime) {
        Graphics g = game.getGraphics();
        List<TouchEvent> touchEvents = game.getInput().getTouchEvents();


        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if (event.type == TouchEvent.TOUCH_UP) {


                if (inBounds(event, 00250250)) {
                    //START GAME
                                game.setScreen(new GameScreen(game));            
      }


            }
        }
    }


    private boolean inBounds(TouchEvent event, int x, int y, int width,
            int height) {
        if (event.x > x && event.x < x + width - 1 && event.y > y
                && event.y < y + height - 1)
            return true;
        else
            return false;
    }


    @Override
    public void paint(float deltaTime) {
        Graphics g = game.getGraphics();
        g.drawImage(Assets.menu00);
    }


    @Override
    public void pause() {
    }


    @Override
    public void resume() {


    }


    @Override
    public void dispose() {


    }


    @Override
    public void backButton() {
        //Display "Exit Game?" Box


    }
}
Notice that here we also have the three methods: update, paint, and backButton.
In addition, we have added an inBounds method that is used to create rectangles with coordinates (x, y, x2, y2).

We use this to create regions in the screen that we can touch to interact with the game (as we do here in the update method). In our case, when the user touches and releases inside the square with side length 250 with a corner at (0, 0), we would call the: game.setScreen(new GameScreen(game));

This is the screen on which we will run our game. Think of this as the StartingClass from Units 2 and 3.

Using the same techniques that we have used in the MenuScreen above, along with the game development techniques from the previous lessons, you should now be able to create your game. Begin experimenting using the sample below. If you ever get stuck, return to Kilobolt.com as I will be continuing Unit 4 by porting our game from Units 2 and 3 to Android. You can see a fully working example here.

In addition, I will be demonstrating how to create a High Scores screen, Splash screen, and demonstrating how to Restart the game once the player dies.

Here's a sample GameScreen.


4. GameScreen class (sample code)
Use this as a starting point for your game!
package com.kilobolt.samplegame;

import java.util.List;

import android.graphics.Color;
import android.graphics.Paint;

import com.kilobolt.framework.Game;
import com.kilobolt.framework.Graphics;
import com.kilobolt.framework.Image;
import com.kilobolt.framework.Screen;
import com.kilobolt.framework.Input.TouchEvent;

public class GameScreen extends Screen {
    enum GameState {
        Ready, Running, Paused, GameOver
    }

    GameState state = GameState.Ready;

    // Variable Setup
    // You would create game objects here.

    int livesLeft = 1;
    Paint paint;

    public GameScreen(Game game) {
        super(game);

        // Initialize game objects here

        // Defining a paint object
        paint = new Paint();
        paint.setTextSize(30);
        paint.setTextAlign(Paint.Align.CENTER);
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);

    }

    @Override
    public void update(float deltaTime) {
        List<TouchEvent> touchEvents = game.getInput().getTouchEvents();

        // We have four separate update methods in this example.
        // Depending on the state of the game, we call different update methods.
        // Refer to Unit 3's code. We did a similar thing without separating the
        // update methods.

        if (state == GameState.Ready)
            updateReady(touchEvents);
        if (state == GameState.Running)
            updateRunning(touchEvents, deltaTime);
        if (state == GameState.Paused)
            updatePaused(touchEvents);
        if (state == GameState.GameOver)
            updateGameOver(touchEvents);
    }

    private void updateReady(List<TouchEvent> touchEvents) {
     
        // This example starts with a "Ready" screen.
        // When the user touches the screen, the game begins. 
        // state now becomes GameState.Running.
        // Now the updateRunning() method will be called!
     
        if (touchEvents.size() > 0)
            state = GameState.Running;
    }

    private void updateRunning(List<TouchEvent> touchEvents, float deltaTime) {
     
        //This is identical to the update() method from our Unit 2/3 game.
     
     
        // 1. All touch input is handled here:
        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);

            if (event.type == TouchEvent.TOUCH_DOWN) {

                if (event.x < 640) {
                    // Move left.
                }

                else if (event.x > 640) {
                    // Move right.
                }

            }

            if (event.type == TouchEvent.TOUCH_UP) {

                if (event.x < 640) {
                    // Stop moving left.
                }

                else if (event.x > 640) {
                    // Stop moving right. }
                }
            }

         
        }
     
        // 2. Check miscellaneous events like death:
     
        if (livesLeft == 0) {
            state = GameState.GameOver;
        }
     
     
        // 3. Call individual update() methods here.
        // This is where all the game updates happen.
        // For example, robot.update();
    }

    private void updatePaused(List<TouchEvent> touchEvents) {
        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if (event.type == TouchEvent.TOUCH_UP) {

            }
        }
    }

    private void updateGameOver(List<TouchEvent> touchEvents) {
        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if (event.type == TouchEvent.TOUCH_UP) {
                if (event.x > 300 && event.x < 980 && event.y > 100
                        && event.y < 500) {
                    nullify();
                    game.setScreen(new MainMenuScreen(game));
                    return;
                }
            }
        }

    }

    @Override
    public void paint(float deltaTime) {
        Graphics g = game.getGraphics();

        // First draw the game elements.

        // Example:
        // g.drawImage(Assets.background, 0, 0);
        // g.drawImage(Assets.character, characterX, characterY);

        // Secondly, draw the UI above the game elements.
        if (state == GameState.Ready)
            drawReadyUI();
        if (state == GameState.Running)
            drawRunningUI();
        if (state == GameState.Paused)
            drawPausedUI();
        if (state == GameState.GameOver)
            drawGameOverUI();

    }

    private void nullify() {

        // Set all variables to null. You will be recreating them in the
        // constructor.
        paint = null;

        // Call garbage collector to clean up memory.
        System.gc();
    }

    private void drawReadyUI() {
        Graphics g = game.getGraphics();

        g.drawARGB(155000);
        g.drawString("Tap each side of the screen to move in that direction.",
                640300, paint);

    }

    private void drawRunningUI() {
        Graphics g = game.getGraphics();

    }

    private void drawPausedUI() {
        Graphics g = game.getGraphics();
        // Darken the entire screen so you can display the Paused screen.
        g.drawARGB(155000);

    }

    private void drawGameOverUI() {
        Graphics g = game.getGraphics();
        g.drawRect(001281801Color.BLACK);
        g.drawString("GAME OVER."640300, paint);

    }

    @Override
    public void pause() {
        if (state == GameState.Running)
            state = GameState.Paused;

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {

    }

    @Override
    public void backButton() {
        pause();
    }
}

 

Leave a Reply

Thanks For Visit Tnl Solution

Subscribe to Posts | Subscribe to Comments

Search Tnl Solution

- Copyright © Total Solution - Tnl Solution - Powered by Blogger TnlLinker - Designed by TalhaSuleman -