Click here to Skip to main content
15,881,757 members
Articles / Programming Languages / Java / Java SE / J2ME

Mobile Game Programming for Beginners: Part 1 of 4

Rate me:
Please Sign up or sign in to vote.
4.91/5 (34 votes)
30 Apr 2009CPOL14 min read 126.4K   3K   80  
First part of four in a beginners' guide to J2ME game programming.
package com.bornander.games.basics;

import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 *
 * @author Fredrik Bornander
 */
public class MainCanvas extends Canvas implements Runnable {
    
    // A reference to the midlet that created this class, used to closing the application.
    private BasicsMIDlet owner;
    
    // The thread that will hold the main game loop.
    private Thread thread = new Thread(this);
    
    // The two images
    private Image avatar;
    private Image target;
    
    // The coordinates of the player.
    private int x = 0;
    private int y = 0;
    
    // The target's coordinates.
    private int targetX;
    private int targetY;
    
    // Flags indicating which buttons are pressed.
    private boolean up = false;
    private boolean down = false;
    private boolean left = false;
    private boolean right = false;
    
    // The gameloop will continue as long as this is true.
    private boolean shouldRun = true;
    
    // This gets set to true when the game is completed.
    private boolean completed = false;
    
    public MainCanvas(BasicsMIDlet owner) throws IOException {
        this.owner = owner;
        avatar = Image.createImage(getClass().getResourceAsStream("/com/bornander/games/basics/resources/avatar.png"));
        target = Image.createImage(getClass().getResourceAsStream("/com/bornander/games/basics/resources/target.png"));
        
        targetX = getWidth() - target.getWidth();
        targetY = getHeight() - target.getHeight();
        
        thread.start();
    }

    /**
     * Detects if the game has been completed (i.e. the avatar has navigated to the target).
     * @return <code>true</code> if the game is completed.
     */
    private boolean isGameCompleted() {
        return x == targetX && y == targetY;
    }
    
    /**
     * Moves the avatar according to the pressed keys.
     */
    private void moveAvatar() {
        if (up)
            --y;
        if (down)
            ++y;
        if (left)
            --x;
        if (right)
            ++x;

        if (y < 0)
            y = 0;
        if (y > getHeight() - avatar.getHeight())
            y = getHeight() - avatar.getHeight();

        if (x < 0)
            x = 0;
        if (x > getWidth() - avatar.getWidth())
            x = getWidth() - avatar.getWidth();        
    }    
    
    /**
     * Renders the game state to screen.
     * This is a overridden method from <code>Canvas>/code>, it is called 
     * automatically for us when we call <code>Canvas.repaint()</code>.
     * @param graphics The graphics object to draw onto.
     */
    protected void paint(Graphics graphics) {

        int w = getWidth();
        int h = getHeight();
        
        graphics.setColor(0x00007F);
        graphics.fillRect(0, 0, w, h);
        
        
        graphics.drawImage(target, targetX, targetY, 0);
        graphics.drawImage(avatar, x, y, 0);

        if (completed) {
            graphics.setColor(0xA0A0FF);
            graphics.setFont(Font.getDefaultFont());
            graphics.drawString("Game Over", w / 2, h / 2, Graphics.BASELINE | Graphics.HCENTER);
        }        
    }

    /**
     * The game's main loop. This will run until the player presses the fire button.
     * It checks for game completed, then moves the avatar, then updates the screen
     * and then sleeps for a little while, and then starts from the beginning again.
     */
    public void run() {
        while(shouldRun) {
            completed = isGameCompleted();

            if (!completed) {
                moveAvatar();
            }            
            
            repaint();
            
            try {
                Thread.sleep(20);
            } 
            catch (InterruptedException ex) {
            }
        } 
        owner.exit();
    }

    /**
     * This gets called for us whenever a key is pressed.
     * @param key The pressed key.
     */
    protected void keyPressed(int key) {
        int gameKey = getGameAction(key);
        switch(gameKey) {
            case Canvas.UP: up = true; break;
            case Canvas.DOWN: down = true; break;
            case Canvas.LEFT: left = true; break;
            case Canvas.RIGHT: right = true; break;
            case Canvas.FIRE: shouldRun = false; break;
        } 
    }

    /**
     * This gets called for us whenever a key is released.
     * @param key The released key.
     */
    protected void keyReleased(int key) {
        int gameKey = getGameAction(key);
        switch(gameKey) {
            case Canvas.UP: up = false; break;
            case Canvas.DOWN: down = false; break;
            case Canvas.LEFT: left = false; break;
            case Canvas.RIGHT: right = false; break;
        } 
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior)
Sweden Sweden
Article videos
Oakmead Apps Android Games

21 Feb 2014: Best VB.NET Article of January 2014 - Second Prize
18 Oct 2013: Best VB.NET article of September 2013
23 Jun 2012: Best C++ article of May 2012
20 Apr 2012: Best VB.NET article of March 2012
22 Feb 2010: Best overall article of January 2010
22 Feb 2010: Best C# article of January 2010

Comments and Discussions