CreatingABasicGameTemplate

Creating a Basic MIDP2.0 Game Template

This tutorial will show you how to create the startup code needed to make MIDP2.0 games for your Java enabled mobile phone.

Things that you need.

You must have the following software installed:

  • JDK 6.0 or higher
  • NetBeans IDE 5.5 or higher Download Site (JDK 6.0 is bundled with NetBeans IDE)
  • NetBeans Mobility Pack for CLDC Download Site


Creating the MIDlet

First off, open Netbeans IDE and create a new mobile application project. What we need is a blank project so remember to uncheck the "Create Hello MIDlet" on the "Name and Location" screen. File:CreatingABasicGameTemplate/newproject2-a CreatingABasicGameTemplate.jpg

Now we need to create the MIDlet ourselves. There are several ways to go about this.

  • By pressing CTRL+N on your keyboard.
  • By choosing New File from the File Menu
  • By right-clicking on the project panel treeview and selecting New, then Midlet

For those of you who used one of the first 2 ways, select MIDP from the categories and MIDlet from the list of file types then click on the "Next" button. File:CreatingABasicGameTemplate/newmidlet1 CreatingABasicGameTemplate.jpg

On the next screen, type in midMain for MIDlet Name. The MIDlet Class Name field will be automatically filled in for you. Leave the MIDlet icon blank for now. As a rule of thumb, never create your files in the "default package". Enter MyGame in the Package field. A folder with the same name will be created inside the project source folder where all source code for your game should go. Click on the "Finish" button. File:CreatingABasicGameTemplate/newmidlet2 CreatingABasicGameTemplate.jpg

Congratulations!! You have succeeded on creating an empty MIDlet that does absolutely nothing.


Creating the Game Canvas

We need to make a canvas based on the new GameCanvas class. The canvas is where we draw all our stuff like images, sprites, maps, scores so it can be shown on the phones screen. It also let's us know what keys were pressed on the phone so we can respond to them.

Choose New File from the File menu. Select Java Classes from the list of categories and Java Class from the list of file types then click on the "Next" button. Alternatively, you can right-click on the package name then choose New and Java Class.

Type in clsCanvas for the Class Name. Make sure to set the Package field to the package name we set earlier for our MIDlet in the first part of this tutorial. Click on the "Finish" button when you're done.
File:CreatingABasicGameTemplate/newclass1 CreatingABasicGameTemplate.jpg


You should see the source code of class file we just created in the editor panel. If not, then navigate to the file from the project panel and double-click on the filename. Except for the author's name and the file/class/package name (if you chose your own), it should look similar to the code below.

*
* clsCanvas.java
*
* Created on October 15, 2007, 7:13 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package MyGame;

/**
*
* @author devlin
*/
public class clsCanvas {
  
   /** Creates a new instance of clsCanvas */
   public clsCanvas() {
   }
  
}


It's now time to turn this class into a GameCanvas class.
Modify this part of the code:

public class clsCanvas {



...into this:


public class clsCanvas extends GameCanvas implements Runnable {

Your code should now look like this:
(I will strip the comments from the code from now on for readability.)

package MyGame;

public class clsCanvas extends GameCanvas implements Runnable {
  
   public clsCanvas() {
   }
}

Press Shift+ALT+F (short cut for Fix Imports) to make sure that all import statements our code requires are detected and added automatically. (Do this periodically or whenever we use a new class or code.)


package MyGame;

import javax.microedition.lcdui.game.GameCanvas;

public class clsCanvas extends GameCanvas implements Runnable {
  
   public clsCanvas() {
   }
}

Now it's time to get rid of those ugly red lines signifying errors in our code. We first need to fulfill the requirements of the base class that we are extending so modify the code further like so:


package MyGame;

import javax.microedition.lcdui.game.GameCanvas;

public class clsCanvas extends GameCanvas implements Runnable {
  
   public clsCanvas() {
       super(true);
   }

   public void run() {
   }

}

Tada! No more errors!

The superclass GameCanvas requires us to implement it's constructor which has one boolean parameter - suppressKeyEvents. Passing the value true stops key events like keyPressed, keyRepeated and keyReleased from being called and optimizing your code. Then how do we respond to user input then? We use the function getKeyStates() to find out what keys were pressed whenever we need them. More on this later.

Our canvas class also implements the Runnable class which allows our game to run on a separate thread. This requires us to implement the run() method. This will contain our main loop and most game related code.

Let's modify the code further to include the main loop for which we will be using a while-loop construct. Modify your run() method like so:


    public void run() {
       while(isRunning){

           flushGraphics();
       }
    }

Add this private variable under the main class declaration statement


public class clsCanvas extends GameCanvas implements Runnable {
private boolean isRunning = true;

One feature of the GameCanvas is an off-screen buffer where everything you draw is first rendered. The contents of this buffer is transferred to the screen after the flushGraphics() function is called. This eliminates flicker and makes your animations smoother. So flushGraphics() is called every time at the end of each loop after you have drawn what you want to be shown on the screen.

With the isRunning variable set to true, the while loop will run forever. We must add a way for the loop to terminate and our program to end. Let's allow the user to end our program when the Fire or 5 key is pressed on the phone. This is where the getKeyStates() function comes in. Modify the run() method like so:


    public void run() {
       int iKey = 0;
       while(isRunning){
           iKey = getKeyStates();
           
           if ((iKey & GameCanvas.FIRE_PRESSED) != 0){
               isRunning = false;
           }

           flushGraphics();
           try{
               Thread.sleep(30);
           } catch (Exception ex){
               
           }
       }
    }

We make the thread sleep or pause for 30 milliseconds after each loop. This keeps the the thread from hogging the processing power of the phone and the game from being unresponsive. Without it, the game will not be able to respond to key presses at the moment it needs to. You can change this value to what you want as long as it works. We will be adding frame limiting at some point and that will dynamically adjust the sleep value and make the frame rate of the game somewhat stable on different phones.

Let's add some drawing code so we can see what we've done later when we run the application.
Add this code in our global variable declarations right under the isRunning declaration:


private boolean isRunning = true;    
private Graphics g;

Add this code in the run() method just before the while loop:


       g = getGraphics();
       while(isRunning){

Add this code inside the run() method just before the flushGraphics() function call:


           //set drawing color to black
           g.setColor(0x000000);
           //fill the whole screen
           g.fillRect(0, 0, getWidth(), getHeight());
           // set drawing color to white
           g.setColor(0xffffff);
           //display the key code last pressed
           g.drawString(Integer.toString(iKey), 2, 2, Graphics.TOP | Graphics.LEFT);

           flushGraphics();

Add this code at the end of the run() method:


       }
       g = null;
    }

Hit Shift+ALT+F to update the imports section and your code should now look like this:


package MyGame;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;

public class clsCanvas extends GameCanvas implements Runnable {
private boolean isRunning = true;    
private Graphics g;

    public clsCanvas() {
        super(true);
    }
    
    public void run() {
       int iKey = 0; 
       g = getGraphics();
       while(isRunning){
           
           iKey = getKeyStates();
           
           if ((iKey & GameCanvas.FIRE_PRESSED) != 0){
               isRunning = false;
           }
           
           //set drawing color to black
           g.setColor(0x000000);
           //fill the whole screen
           g.fillRect(0, 0, getWidth(), getHeight());
           // set drawing color to white
           g.setColor(0xffffff);
           //display the key code last pressed
           g.drawString(Integer.toString(iKey), 2, 2, Graphics.TOP | Graphics.LEFT);

           flushGraphics();
           
           try{
               Thread.sleep(30);
           } catch (Exception ex){
               
           }
       }
       g = null;
    }
}

Notice we declared a new Graphics object named g. The Graphics object contains the methods we must use to draw stuff on the GameCanvas. Just take note that the color passed when setColor() is called will apply to succeeding calls to drawing methods until setColor() is called again with a different color. The Graphics object is also declared as a global variable and is assigned to the actual object right before the main loop. This saves us from having to call the getGraphics() method of the GameCanvas over and over.


Displaying the GameCanvas

In this last part of this tutorial , we will modify the code of our MIDlet and Canvas classes to make the both ends meet and the application to run.

First, we'll need to add a new global variable to reference the MIDlet from the canvas class. Let's call it fParent. So add this code to clsCanvas like so:


private Graphics g;
private midMain fParent;

Modify the contructor to accept the MIDlet class as a parameter and assign the value to our global variable:


    public clsCanvas(midMain m) {
        super(true);
        fParent = m;
    }

The canvas needs a way to notify the MIDlet that the main loop has ended and the program needs to terminate. Add this code at the end of our run() method:


       }
       g = null;
       fParent.destroyApp(false);
       fParent = null;
    }


We need a new method that the MIDlet can call to start the game thread. Let's call it the start() method and add the code under the clsCanvas constructor:


    public void start(){
        Thread runner = new Thread(this);
        runner.start();
    }

You should press Shift+ALT+F after editing the code...just in case.

Here's the completed clsCanvas source code:


package MyGame;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;

public class clsCanvas extends GameCanvas implements Runnable {
private boolean isRunning = true;    
private Graphics g;
private midMain fParent;

    public clsCanvas(midMain m) {
        super(true);
        fParent = m;
    }
    
    public void start(){
        Thread runner = new Thread(this);
        runner.start();
    }

    public void run() {
       int iKey = 0; 
       g = getGraphics();
       while(isRunning){
           
           iKey = getKeyStates();
           
           if ((iKey & GameCanvas.FIRE_PRESSED) != 0){
               isRunning = false;
           }
           
           //set drawing color to black
           g.setColor(0x000000);
           //fill the whole screen
           g.fillRect(0, 0, getWidth(), getHeight());
           // set drawing color to white
           g.setColor(0xffffff);
           //display the key code last pressed
           g.drawString(Integer.toString(iKey), 2, 2, Graphics.TOP | Graphics.LEFT);
           flushGraphics();
           
           try{
               Thread.sleep(30);
           } catch (Exception ex){
               
           }
       }
       g = null;
       fParent.destroyApp(false);
       fParent = null;
    }
}

Now open the source code of our MIDlet. We will define a new global variable called myCanvas that will allow the MIDlet to create and reference the clsCanvas class. Place the code just under the midMain class declaration:


public class midMain extends MIDlet {
    clsCanvas myCanvas;

Next, we will modify the startApp() method of our midlet so that it creates a new instance of the clsCanvas class, starts it in a new thread, and finally making the the canvas the current displayed item. Add this code to the startApp() method:


    public void startApp() {
        Display d = Display.getDisplay(this);
        myCanvas = new clsCanvas(this);
        myCanvas.start();
        d.setCurrent(myCanvas);
    }

The last code we will add is for making sure we release all the resources our MIDlet has used and terminate gracefully when your game has ended. Place this code in the destroyApp() method:


    public void destroyApp(boolean unconditional) {
        myCanvas = null;
        notifyDestroyed();
    }

Here's the completed midMain source code:


package MyGame;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class midMain extends MIDlet {
    clsCanvas myCanvas;
    
    public void startApp() {
        Display d = Display.getDisplay(this);
        myCanvas = new clsCanvas(this);
        myCanvas.start();
        d.setCurrent(myCanvas);
    }
    
    public void pauseApp() {
    }
    
    public void destroyApp(boolean unconditional) {
        myCanvas = null;
        notifyDestroyed();
    }
}

Yay! We're done! You can now test your MIDlet by pressing the F6 key on your keyboard or clicking on the Run Main Project icon on the toolbar. You should see the phone emulator popup and your MIDlet highlighted at the top of the Screen. You can run the MIDlet by pressing the Enter key on your keyboard, clicking the "Select" button on the emulator. or clicking on the softkey button labeled "Launch".

That ends our tutorial on creating a basic template for your game. Have fun.

Full Source Code

You can download the project source code from this tutorial here: BasicGameTemplate_CreatingABasicGameTemplate.zip (26Kb)

Got a question or a comment? You can visit my blog at devlinslab.blogspot.com
by Glenn John M. Geronimo

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo