MIDP2.0(Mobile Internet Device Profile)技术进行游戏开发中用到的最重要的包是:javax.microedition.lcdui.game,本文通过对样例游戏Tumbleweed的代码分析,将展示MIDP2.0技术的几个主要部分。游戏的主要情景是一个牛仔跳着闪避风滚草,这是一个简单的游戏,但你可以从中学到将来写复杂游戏必须具备的大部分基础知识。
从MIDlet类开始
象通常一样,应用从MIDlet类开始。本例中,我的MIDlet子类是Jump。Jump类几乎是完全继承的MIDIet子类,唯一的不同是用到了另一个独立类GameThread,用来动态设置当前窗口允许的有效按钮,比如当游戏处于非暂停状态时,玩家才可以使用暂停这个有效按钮,而激活按钮有效则是在游戏处于暂停状态时候,与此类似游戏停止后,开始按钮才是有效按钮。
Listing 1是游戏的MIDlet子类——Jump.java源码。
Listing 1. Jump.java
package net.frog_parrot.jump;
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);
//--------------------------------------------------------- // Game object fields
/** * The canvas that all of the game will be drawn on. */ private JumpCanvas myCanvas;
/** * The thread that advances the cowboy. */ private GameThread myGameThread;
//----------------------------------------------------- // Initialization and game state changes /** * Initialize the canvas and the commands. */ public Jump() { try { myCanvas = new JumpCanvas(this); myCanvas.addCommand(myExitCommand); 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 you always check fields for null // before calling methods on them.
/** * Start the application. */ public void startApp() throws MIDletStateChangeException { if(myCanvas != null) { if(myGameThread == null) { myGameThread = new GameThread(myCanvas); myCanvas.start(); myGameThread.start(); } else { myCanvas.removeCommand(myGoCommand); myCanvas.addCommand(myPauseCommand); myCanvas.flushKeys(); myGameThread.resumeGame(); } } }
/** * Stop and throw out the garbage. */ public void destroyApp(boolean unconditional) throws MIDletStateChangeException { if(myGameThread != null) { myGameThread.requestStop(); } myGameThread = null; myCanvas = null; System.gc(); }
/** * Request the thread to pause. */ public void pauseApp() { if(myCanvas != null) { setGoCommand(); } If(myGameThread != null) { myGameThread.pauseGame(); } }
//---------------------------------------------------------------- // Implementation of CommandListener /* * Respond to a command issued on the Canvas. * (either reset or exit). */ public void commandAction(Command c, Displayable s) { if(c == myGoCommand) { myCanvas.removeCommand(myGoCommand); myCanvas.addCommand(myPauseCommand); myCanvas.flushKeys(); myGameThread.resumeGame(); } else if(c == myPauseCommand) { myCanvas.removeCommand(myPauseCommand); myCanvas.addCommand(myGoCommand); myGameThread.pauseGame(); } else if(c == myNewCommand) { myCanvas.removeCommand(myNewCommand); myCanvas.addCommand(myPauseCommand); myCanvas.reset(); myGameThread.resumeGame(); } else if((c == myExitCommand) || (c == Alert.DISMISS_COMMAND)) { try { destroyApp(false); notifyDestroyed(); } catch (MIDletStateChangeException ex) { } } }
//------------------------------------------------------- // 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); } } |
|
|