Tumbleweed game : Game « J2ME « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » J2ME » GameScreenshots 
Tumbleweed game

/*
 Title:  J2ME Games With MIDP2
 Authors:  Carol Hamer
 Publisher:  Apress
 ISBN:   1590593820
 */

import javax.microedition.media.*;
import javax.microedition.media.control.*;

import java.util.Random;

import javax.microedition.lcdui.game.*;

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

/**
 * This is the main class of the tumbleweed game.
 
 @author Carol Hamer
 */
public class Jump extends MIDlet implements CommandListener {

  //---------------------------------------------------------
  //   commands

  /**
   * the command to end the game.
   */
  private Command myExitCommand = new Command("Exit", Command.EXIT, 99);

  /**
   * the command to start moving when the game is paused.
   */
  private Command myGoCommand = new Command("Go", Command.SCREEN, 1);

  /**
   * the command to pause the game.
   */
  private Command myPauseCommand = new Command("Pause", Command.SCREEN, 1);

  /**
   * the command to start a new game.
   */
  private Command myNewCommand = new Command("Play Again", Command.SCREEN, 1);

  /**
   * The command to start/pause the music. (This command may appear in a menu)
   */
  private Command myMusicCommand = new Command("Music", Command.SCREEN, 2);

  //---------------------------------------------------------
  //   game object fields

  /**
   * the the canvas that all of the game will be drawn on.
   */
  private JumpCanvas myCanvas;

  //---------------------------------------------------------
  //   thread fields

  /**
   * the thread that advances the cowboy.
   */
  private GameThread myGameThread;

  /**
   * The class that plays music if the user wants.
   */
  //private MusicMaker myMusicMaker;
  private ToneControlMusicMaker myMusicMaker;

  /**
   * The thread tha sets tumbleweeds in motion at random intervals.
   */
  private TumbleweedThread myTumbleweedThread;

  /**
   * if the user has paused the game.
   */
  private boolean myGamePause;

  /**
   * if the game is paused because it is hidden.
   */
  private boolean myHiddenPause;

  //-----------------------------------------------------
  //    initialization and game state changes

  /**
   * Initialize the canvas and the commands.
   */
  public Jump() {
    try {
      myCanvas = new JumpCanvas(this);
      myCanvas.addCommand(myExitCommand);
      myCanvas.addCommand(myMusicCommand);
      myCanvas.addCommand(myPauseCommand);
      myCanvas.setCommandListener(this);
    catch (Exception e) {
      errorMsg(e);
    }
  }

  /**
   * Switch the command to the play again command.
   */
  void setNewCommand() {
    myCanvas.removeCommand(myPauseCommand);
    myCanvas.removeCommand(myGoCommand);
    myCanvas.addCommand(myNewCommand);
  }

  /**
   * Switch the command to the go command.
   */
  private void setGoCommand() {
    myCanvas.removeCommand(myPauseCommand);
    myCanvas.removeCommand(myNewCommand);
    myCanvas.addCommand(myGoCommand);
  }

  /**
   * Switch the command to the pause command.
   */
  private void setPauseCommand() {
    myCanvas.removeCommand(myNewCommand);
    myCanvas.removeCommand(myGoCommand);
    myCanvas.addCommand(myPauseCommand);
  }

  //----------------------------------------------------------------
  //  implementation of MIDlet
  // these methods may be called by the application management
  // software at any time, so we always check fields for null
  // before calling methods on them.

  /**
   * Start the application.
   */
  public void startApp() throws MIDletStateChangeException {
    try {
      if (myCanvas != null) {
        myCanvas.start();
        myCanvas.flushKeys();
        systemStartThreads();
      }
    catch (Exception e) {
      errorMsg(e);
    }
  }

  /**
   * stop and throw out the garbage.
   */
  public void destroyApp(boolean unconditional)
      throws MIDletStateChangeException {
    try {
      stopThreads();
      myCanvas = null;
      System.gc();
    catch (Exception e) {
      errorMsg(e);
    }
  }

  /**
   * request the game to pause. This method is called by the application
   * management software, not in response to a user pausing the game.
   */
  public void pauseApp() {
    try {
      if (myCanvas != null) {
        setGoCommand();
        systemPauseThreads();
      }
    catch (Exception e) {
      errorMsg(e);
    }
  }

  //----------------------------------------------------------------
  //  implementation of CommandListener

  /*
   * Respond to a command issued on the Canvas. (either reset or exit).
   */
  public void commandAction(Command c, Displayable s) {
    try {
      if (c == myGoCommand) {
        myCanvas.removeCommand(myGoCommand);
        myCanvas.addCommand(myPauseCommand);
        myCanvas.flushKeys();
        userStartThreads();
      else if (c == myPauseCommand) {
        myCanvas.removeCommand(myPauseCommand);
        myCanvas.addCommand(myGoCommand);
        userPauseThreads();
      else if (c == myNewCommand) {
        myCanvas.removeCommand(myNewCommand);
        myCanvas.addCommand(myPauseCommand);
        System.gc();
        myCanvas.reset();
        myCanvas.flushKeys();
        myHiddenPause = false;
        myGamePause = false;
        startThreads();
      else if (c == myMusicCommand) {
        if (myMusicMaker != null) {
          myMusicMaker.toggle();
          myCanvas.repaint();
          myCanvas.serviceRepaints();
        }
      else if ((c == myExitCommand)/* || (c == Alert.DISMISS_COMMAND)*/) {
        try {
          destroyApp(false);
          notifyDestroyed();
        catch (MIDletStateChangeException ex) {
        }
      }
    catch (Exception e) {
      errorMsg(e);
    }
  }

  //-------------------------------------------------------
  //  thread methods

  /**
   * start up all of the game's threads. Creates them if necessary. to be
   * called when the user hits the go command.
   */
  private synchronized void userStartThreads() throws Exception {
    myGamePause = false;
    if (!myHiddenPause) {
      startThreads();
    }
  }

  /**
   * start up all of the game's threads. Creates them if necessary. used by
   * showNotify
   */
  synchronized void systemStartThreads() throws Exception {
    myHiddenPause = false;
    if (!myGamePause) {
      startThreads();
    }
  }

  /**
   * start up all of the game's threads. Creates them if necessary. internal
   * version. note: if this were synchronized, whould it cause deadlock?
   */
  private void startThreads() throws Exception {
    if (myGameThread == null) {
      myGameThread = new GameThread(myCanvas);
      myGameThread.start();
    else {
      myGameThread.resumeGame();
    }
    if (myTumbleweedThread == null) {
      myTumbleweedThread = new TumbleweedThread(myCanvas);
      myTumbleweedThread.start();
    else {
      myTumbleweedThread.resumeGame();
    }
    if (myMusicMaker == null) {
      myMusicMaker = new ToneControlMusicMaker();
      //myMusicMaker = new MusicMaker();
      myMusicMaker.start();
    else {
      myMusicMaker.resumeGame();
    }
  }

  /**
   * Pause all of the threads started by this game. to be called when the user
   * hits the pause command.
   */
  synchronized void userPauseThreads() {
    myGamePause = true;
    pauseThreads();
  }

  /**
   * Pause all of the threads started by this game. used by hideNotify
   */
  void systemPauseThreads() {
    myHiddenPause = true;
    pauseThreads();
  }

  /**
   * start up all of the game's threads. Creates them if necessary. internal
   * version. note: if this were synchronized, whould it cause deadlock?
   */
  private void pauseThreads() {
    if (myGameThread != null) {
      myGameThread.pauseGame();
    }
    if (myTumbleweedThread != null) {
      myTumbleweedThread.pauseGame();
    }
    if (myMusicMaker != null) {
      myMusicMaker.pauseGame();
    }
  }

  /**
   * Stop all of the threads started by this game and delete them as they are
   * no longer usable.
   */
  private synchronized void stopThreads() {
    if (myGameThread != null) {
      myGameThread.requestStop();
    }
    if (myTumbleweedThread != null) {
      myTumbleweedThread.requestStop();
    }
    if (myMusicMaker != null) {
      myMusicMaker.requestStop();
    }
    myGameThread = null;
    myTumbleweedThread = null;
    myMusicMaker = null;
  }

  //-------------------------------------------------------
  //  error methods

  /**
   * Converts an exception to a message and displays the message..
   */
  void errorMsg(Exception e) {
    if (e.getMessage() == null) {
      errorMsg(e.getClass().getName());
    else {
      errorMsg(e.getClass().getName() ":" + e.getMessage());
    }
  }

  /**
   * Displays an error message alert if something goes wrong.
   */
  void errorMsg(String msg) {
    Alert errorAlert = new Alert("error", msg, null, AlertType.ERROR);
    errorAlert.setCommandListener(this);
    errorAlert.setTimeout(Alert.FOREVER);
    Display.getDisplay(this).setCurrent(errorAlert);
  }

}

/**
 * This class is the display of the game.
 
 @author Carol Hamer
 */

class JumpCanvas extends javax.microedition.lcdui.game.GameCanvas {

  //---------------------------------------------------------
  //   dimension fields
  //  (constant after initialization)

  /**
   * the height of the green region below the ground.
   */
  static final int GROUND_HEIGHT = 32;

  /**
   * a screen dimension.
   */
  static final int CORNER_X = 0;

  /**
   * a screen dimension.
   */
  static final int CORNER_Y = 0;

  /**
   * a screen dimension.
   */
  static int DISP_WIDTH;

  /**
   * a screen dimension.
   */
  static int DISP_HEIGHT;

  /**
   * a font dimension.
   */
  static int FONT_HEIGHT;

  /**
   * the default font.
   */
  static Font FONT;

  /**
   * a font dimension.
   */
  static int SCORE_WIDTH;

  /**
   * The width of the string that displays the time, saved for placement of
   * time display.
   */
  static int TIME_WIDTH;

  /**
   * color constant
   */
  public static final int BLACK = 0;

  /**
   * color constant
   */
  public static final int WHITE = 0xffffff;

  //---------------------------------------------------------
  //   game object fields

  /**
   * a handle to the display.
   */
  private Display myDisplay;

  /**
   * a handle to the MIDlet object (to keep track of buttons).
   */
  private Jump myJump;

  /**
   * the LayerManager that handles the game graphics.
   */
  private JumpManager myManager;

  /**
   * whether or not the game has ended.
   */
  private boolean myGameOver;

  /**
   * the player's score.
   */
  private int myScore = 0;

  /**
   * How many ticks we start with.
   */
  private int myInitialGameTicks = 950;

  /**
   * this is saved to determine if the time string needs to be recomputed.
   */
  private int myOldGameTicks = myInitialGameTicks;

  /**
   * the number of game ticks that have passed.
   */
  private int myGameTicks = myOldGameTicks;

  /**
   * we save the time string to avoid recreating it unnecessarily.
   */
  private static String myInitialString = "1:00";

  /**
   * we save the time string to avoid recreating it unnecessarily.
   */
  private String myTimeString = myInitialString;

  //-----------------------------------------------------
  //    gets/sets

  /**
   * This is called when the game ends.
   */
  void setGameOver() {
    myGameOver = true;
    myJump.userPauseThreads();
  }

  /**
   @return a handle to the tumbleweed objects.
   */
  Tumbleweed[] getTumbleweeds() {
    return (myManager.getTumbleweeds());
  }

  //-----------------------------------------------------
  //    initialization and game state changes

  /**
   * Constructor sets the data, performs dimension calculations, and creates
   * the graphical objects.
   */
  public JumpCanvas(Jump midletthrows Exception {
    super(false);
    myDisplay = Display.getDisplay(midlet);
    myJump = midlet;
    // calculate the dimensions
    DISP_WIDTH = getWidth();
    DISP_HEIGHT = getHeight();
    Display disp = Display.getDisplay(myJump);
    if (disp.numColors() 256) {
      throw (new Exception("game requires 256 shades"));
    }
    if ((DISP_WIDTH < 150|| (DISP_HEIGHT < 170)) {
      throw (new Exception("Screen too small"));
    }
    if ((DISP_WIDTH > 250|| (DISP_HEIGHT > 250)) {
      throw (new Exception("Screen too large"));
    }
    FONT = getGraphics().getFont();
    FONT_HEIGHT = FONT.getHeight();
    SCORE_WIDTH = FONT.stringWidth("Score: 000");
    TIME_WIDTH = FONT.stringWidth("Time: " + myInitialString);
    if (myManager == null) {
      myManager = new JumpManager(CORNER_X, CORNER_Y + FONT_HEIGHT * 2,
          DISP_WIDTH, DISP_HEIGHT - FONT_HEIGHT * - GROUND_HEIGHT);
    }
  }

  /**
   * This is called as soon as the application begins.
   */
  void start() {
    myGameOver = false;
    myDisplay.setCurrent(this);
    repaint();
  }

  /**
   * sets all variables back to their initial positions.
   */
  void reset() {
    myManager.reset();
    myScore = 0;
    myGameOver = false;
    myGameTicks = myInitialGameTicks;
    myOldGameTicks = myInitialGameTicks;
    repaint();
  }

  /**
   * clears the key states.
   */
  void flushKeys() {
    getKeyStates();
  }

  /**
   * pause the game when it's hidden.
   */
  protected void hideNotify() {
    try {
      myJump.systemPauseThreads();
    catch (Exception oe) {
      myJump.errorMsg(oe);
    }
  }

  /**
   * When it comes back into view, unpause it.
   */
  protected void showNotify() {
    try {
      myJump.systemStartThreads();
    catch (Exception oe) {
      myJump.errorMsg(oe);
    }
  }

  //-------------------------------------------------------
  //  graphics methods

  /**
   * paint the game graphic on the screen.
   */
  public void paint(Graphics g) {
    // clear the screen:
    g.setColor(WHITE);
    g.fillRect(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT);
    // color the grass green
    g.setColor(02550);
    g.fillRect(CORNER_X, CORNER_Y + DISP_HEIGHT - GROUND_HEIGHT,
        DISP_WIDTH, DISP_HEIGHT);
    // paint the layer manager:
    try {
      myManager.paint(g);
    catch (Exception e) {
      myJump.errorMsg(e);
    }
    // draw the time and score
    g.setColor(BLACK);
    g.setFont(FONT);
    g.drawString("Score: " + myScore, (DISP_WIDTH - SCORE_WIDTH2,
        DISP_HEIGHT + - GROUND_HEIGHT, g.TOP | g.LEFT);
    g.drawString("Time: " + formatTime()(DISP_WIDTH - TIME_WIDTH2,
        CORNER_Y + FONT_HEIGHT, g.TOP | g.LEFT);
    // write game over if the game is over
    if (myGameOver) {
      myJump.setNewCommand();
      // clear the top region:
      g.setColor(WHITE);
      g.fillRect(CORNER_X, CORNER_Y, DISP_WIDTH, FONT_HEIGHT * 1);
      int goWidth = FONT.stringWidth("Game Over");
      g.setColor(BLACK);
      g.setFont(FONT);
      g.drawString("Game Over"(DISP_WIDTH - goWidth2, CORNER_Y
          + FONT_HEIGHT, g.TOP | g.LEFT);
    }
  }

  /**
   * a simple utility to make the number of ticks look like a time...
   */
  public String formatTime() {
    if ((myGameTicks / 16!= myOldGameTicks) {
      myTimeString = "";
      myOldGameTicks = (myGameTicks / 161;
      int smallPart = myOldGameTicks % 60;
      int bigPart = myOldGameTicks / 60;
      myTimeString += bigPart + ":";
      if (smallPart / 10 1) {
        myTimeString += "0";
      }
      myTimeString += smallPart;
    }
    return (myTimeString);
  }

  //-------------------------------------------------------
  //  game movements

  /**
   * Tell the layer manager to advance the layers and then update the display.
   */
  void advance() {
    myGameTicks--;
    myScore += myManager.advance(myGameTicks);
    if (myGameTicks == 0) {
      setGameOver();
    }
    // paint the display
    try {
      paint(getGraphics());
      flushGraphics();
    catch (Exception e) {
      myJump.errorMsg(e);
    }
  }

  /**
   * Respond to keystrokes.
   */
  public void checkKeys() {
    if (!myGameOver) {
      int keyState = getKeyStates();
      if ((keyState & LEFT_PRESSED!= 0) {
        myManager.setLeft(true);
      }
      if ((keyState & RIGHT_PRESSED!= 0) {
        myManager.setLeft(false);
      }
      if ((keyState & UP_PRESSED!= 0) {
        myManager.jump();
      }
    }
  }

}

/**
 * This class draws the background grass.
 
 @author Carol Hamer
 */

class Grass extends TiledLayer {

  //---------------------------------------------------------
  //    dimension fields
  //  (constant after initialization)

  /**
   * The width of the square tiles that make up this layer..
   */
  static final int TILE_WIDTH = 20;

  /**
   * This is the order that the frames should be displayed for the animation.
   */
  static final int[] FRAME_SEQUENCE = 232};

  /**
   * This gives the number of squares of grass to put along the bottom of the
   * screen.
   */
  static int COLUMNS;

  /**
   * After how many tiles does the background repeat.
   */
  static final int CYCLE = 5;

  /**
   * the fixed Y coordinate of the strip of grass.
   */
  static int TOP_Y;

  //---------------------------------------------------------
  //    instance fields

  /**
   * Which tile we are currently on in the frame sequence.
   */
  private int mySequenceIndex = 0;

  /**
   * The index to use in the static tiles array to get the animated tile..
   */
  private int myAnimatedTileIndex;

  //---------------------------------------------------------
  //   gets / sets

  /**
   * Takes the width of the screen and sets my columns to the correct
   * corresponding number
   */
  static int setColumns(int screenWidth) {
    COLUMNS = ((screenWidth / 2013;
    return (COLUMNS);
  }

  //---------------------------------------------------------
  //   initialization

  /**
   * constructor initializes the image and animation.
   */
  public Grass() throws Exception {
    super(setColumns(JumpCanvas.DISP_WIDTH)1, Image
        .createImage("/images/grass.png"), TILE_WIDTH, TILE_WIDTH);
    TOP_Y = JumpManager.DISP_HEIGHT - TILE_WIDTH;
    setPosition(0, TOP_Y);
    myAnimatedTileIndex = createAnimatedTile(2);
    for (int i = 0; i < COLUMNS; i++) {
      if ((i % CYCLE == 0|| (i % CYCLE == 2)) {
        setCell(i, 0, myAnimatedTileIndex);
      else {
        setCell(i, 01);
      }
    }
  }

  //---------------------------------------------------------
  //   graphics

  /**
   * sets the grass back to its initial position..
   */
  void reset() {
    setPosition(-(TILE_WIDTH * CYCLE), TOP_Y);
    mySequenceIndex = 0;
    setAnimatedTile(myAnimatedTileIndex, FRAME_SEQUENCE[