呵呵,昨天晚上开始学习手机游戏编写,现在现学现卖,希望可以帮到一些初手.:).
Step1.安装J2se SDK, j2sdk-1_4_2_08-windows-i586-p.exe/到C:/j2sdk1.4.2_08目录
Step2.我的电脑->属性->高级->环境变量,设置PATH路径加上: C:/j2sdk1.4.2_08/bin;
Step3.安装Motorola J2ME SDK for Linux OS Products,Mot_Linux_5.4.2.exe到目录C:/Motorola/5.4.2/
Step4.在D:/创建以下目录结构D:/com/snake
Step5.创建目录结构D:/com/snake/res/audio,复制C:/WINDOWS/Media/recycle.wav到D:/com/snake/res/audio目录下.
Step6.创建并编写D:/com/snake/snake.jad,内容如下:
- MIDlet-1: SnakeGame, ,com.snake.SnakeGame
- MIDlet-Jar-Size: 9512
- MIDlet-Jar-URL: snake.jar
- MIDlet-Name: SnakeGame
- MIDlet-Vendor: yourname@21cn.com
- MIDlet-Version: 1.0
Step7.创建并编写D:/com/snake/manifest.mf,内容如下:
- Manifest-Version: 1.0
- MIDlet-Name: Snake
- MIDlet-1: SnakeGame, ,com.snake.SnakeGame
- MIDlet-Version: 1.0
- MIDlet-Vendor: yourname@21cn.com
- MicroEdition-Configuration: CLDC-1.0
- MicroEdition-Profile: MIDP-1.0
- MIDlet-Description: Snake Game For Mobile Phone
Step8.创建并编写D:/makeSnakeEM3.bat,内容如下:
- @rem ***************************************************************
- @rem ** Copyright (c) 2002-2003 Motorola, Inc. All rights reserved.
- @rem **
- @rem ** makeOneEM1.bat
- @rem **
- @rem ** This script compiles one of the demo MIDlets.
- @rem **
- @rem ** Command Line Parameters:
- @rem ** - Location of .JAVA files to compile
- @rem ** - Location of Emulator
- @rem **
- @rem **
- @rem ** Assumptions:
- @rem ** - This script is invoked from the demo/scripts directory
- @rem ** - Demo midlets are in the package com
- @rem ** - The directory demo/com exists.
- @rem ** - Default behavior is to compile bounce for the Monty emulator
- @rem ** - Java 1.2 compiler can be invoked:
- @rem ** + javac.exe is on the PATH
- @rem **
- @rem ** Results:
- @rem ** - One of the potential targets will be created in it's directory
- @rem ** - Each output class will be written to a .JAR file
- @rem **
- @rem **
- @rem ***************************************************************
- @echo off
- set MOTOSDKPATH=C:/Motorola/5.4.2/
- @rem ***************************************************************
- @rem ** Check to see if a command line argument was specified
- @rem ** First argument must be the target MIDlet name
- @rem ***************************************************************
- del com/snake/*.class
- @if NOT "%1"=="" set COMPILETARG=%1
- @if "%1"=="" set COMPILETARG=snake
- @rem ***************************************************************
- @rem ** Set the COMPILECLASS variable to point to the midlet dir
- @rem ** then append the name of the target MIDlet
- @rem ***************************************************************
- set COMPILECLASS=com/%COMPILETARG%
- @rem ***************************************************************
- @rem ** Check to see if a command line argument was specified
- @rem ** Second argument must be the target Emulator name
- @rem ***************************************************************
- @if NOT "%2"=="" set TARGETEMUL=%2
- @if "%2"=="" set TARGETEMUL=EmulatorM.3
- @rem ***************************************************************
- @rem ** Next 3 lines can be un-REMarked to help with debugging
- @rem ** a problematic build.
- @rem ***************************************************************
- @rem set COMPILETARG
- @rem set COMPILECLASS
- @rem set TARGETEMUL
- @echo Compiling ...
- @echo off
- @rem ***************************************************************
- @rem ** Change to the demo root dir
- @rem **
- @rem ***************************************************************
- @rem ***************************************************************
- @rem ** Compile using the specified emulator and target MIDlet
- @rem ** source files
- @rem ***************************************************************
- @echo javac -target 1.1 -O -classpath %MOTOSDKPATH%/%TARGETEMUL%/lib/midp.zip %COMPILECLASS%/*.java
- javac -target 1.1 -O -classpath %MOTOSDKPATH%/%TARGETEMUL%/lib/midp.zip %COMPILECLASS%/*.java
- @echo Creating JAR ...
- @echo off
- @rem ***************************************************************
- @rem ** Now create the .JAR file in the directory with the sources
- @rem ** include the manifest, stored in meta-inf
- @rem ***************************************************************
- @echo off
- jar cmf %COMPILECLASS%/manifest.mf %COMPILECLASS%/%COMPILETARG%.jar %COMPILECLASS%/*.class
- @rem ***************************************************************
- @rem ** See if the target midlet has any resources that will need
- @rem ** to be included in the .JAR
- @rem ***************************************************************
- echo jar uf ../%COMPILETARG%.jar *
- cd %COMPILECLASS%/res
- jar uf ../%COMPILETARG%.jar *
- cd ../../../
- :JARCOMPLETE
- @echo Preverifying ...
- @echo off
- @rem ***************************************************************
- @rem ** Use the preverifier that is supplied with the emulator
- @rem **
- @rem ***************************************************************
- @echo off
- %MOTOSDKPATH%/%TARGETEMUL%/bin/preverify -classpath %MOTOSDKPATH%/%TARGETEMUL%/lib;%MOTOSDKPATH%/%TARGETEMUL%/bin;%MOTOSDKPATH%/%TARGETEMUL%/lib/midp.zip -d %COMPILECLASS% %COMPILECLASS%/%COMPILETARG%.jar
- @rem ***************************************************************
- @rem ** Extract the preverified classes from the .JAR file. These
- @rem ** will be runnable if there are no resources involved.
- @rem ***************************************************************
- @echo off
- @echo Restoring preverified classes...
- jar xf %COMPILECLASS%/%COMPILETARG%.jar %COMPILECLASS%/*.class
Step8.创建并编写D:/com/snake/SnakeGame.java,内容如下:
- /*
- * SnakeGame.java
- *
- * 2008-9-21 17:32
- *
- * This notice does not imply publication.
- */
- package com.snake;
- import java.util.Vector;
- import java.util.Random;
- import javax.microedition.lcdui.*;
- import javax.microedition.midlet.*;
- import javax.microedition.media.Player;
- import javax.microedition.media.Manager;
- import javax.microedition.media.MediaException;
- import java.io.IOException;
- import java.io.InputStream;
- /**
- *
- * @see MIDlet
- */
- public class SnakeGame extends MIDlet implements CommandListener{
- /**
- * The game speed (in milliseconds)
- */
- private final int GAME_SPEED = 200;
- /**
- * The main game screen
- */
- private GameFrame mainFrame;
- /**
- * The title screen
- */
- private Form titleScreen;
- /**
- * The results screen
- */
- private Form statsScreen;
- /**
- * The Snake Movie Clip object for this game
- */
- private SnakeMc mySnakeMc;
- /**
- * True if game has not started or player lost
- */
- private boolean gameOver = true;
- /**
- * Reference to Display
- */
- private Display myDisplay;
- /**
- * The repaint lock for this Bounce MIDlet
- */
- public Object repaintLock = new Object();
- public Object playSoundLock = new Object();
- private int playSound=0;
- private SoundPlayer soundPlayer=null;
- /**
- * How many games have been played
- */
- private int numGames=0;
- /**
- * The number of milliseconds the user has been playing this game
- */
- private long elapsedTime;
- public SnakeGame() {
- myDisplay = Display.getDisplay(this);
- /*
- * Create main game screen
- */
- mainFrame = new GameFrame();
- /*
- * Create title screen
- */
- titleScreen = new Form("贪吃蛇");
- titleScreen.append(new StringItem(null,
- "很经典的游戏哦,希望你喜欢。 /n联系作者: dany21cn@21cn.com"));
- titleScreen.setCommandListener(this);
- titleScreen.addCommand(new Command("开始", Command.OK, 1));
- /*
- * Create results screen
- */
- statsScreen = new Form("游戏统计");
- statsScreen.setCommandListener(SnakeGame.this);
- statsScreen.addCommand(new Command("再玩一局?", Command.OK, 1));
- }
- /**
- * Begin the application, show its frame
- */
- protected void startApp() {
- myDisplay.setCurrent(titleScreen);
- }
- /**
- * Application is being terminated, kill threads
- */
- protected void pauseApp() {
- gameOver = true;
- mySnakeMc = null;
- }
- /**
- * Clean up application
- */
- protected void destroyApp(boolean unconditional) {
- gameOver = true;
- }
- /**
- * Start the game
- */
- public void commandAction(Command c, Displayable d) {
- /*
- * Create Sound Play And Snake Game threads
- */
- mySnakeMc = new SnakeMc();
- soundPlayer = new SoundPlayer();
- /*
- * Get the starting time
- */
- elapsedTime = System.currentTimeMillis();
- /*
- * Set the initial Snake positions
- */
- mySnakeMc.setUp();
- /*
- * Set the screen
- */
- myDisplay.setCurrent(mainFrame);
- /*
- * Start the thread
- */
- gameOver = false;
- playSound =0;
- soundPlayer.start();
- mySnakeMc.start();
- }
- public class SnakeBlock
- {
- public int r=2;
- public int x=0;
- public int y=0;
- public int xx=0;
- public int yy=0;
- public SnakeBlock()
- {
- super();
- }
- }
- /**
- * The main Screen for this game
- */
- class GameFrame extends Canvas {
- Font font = Font.getFont(Font.FACE_MONOSPACE,
- Font.STYLE_PLAIN, Font.SIZE_SMALL);
- int gameAction = 0;
- /**
- * Canvas receives all key events
- */
- public void keyPressed(int keyCode) {
- synchronized (SnakeGame.this.repaintLock){
- try {
- gameAction = getGameAction(keyCode);
- } catch (Exception e) {
- }
- if (gameAction == LEFT) {
- mySnakeMc.kbq.addElement(new Integer(0));
- } else if (gameAction == RIGHT) {
- mySnakeMc.kbq.addElement(new Integer(2));
- }
- else if(gameAction == UP)
- {
- mySnakeMc.kbq.addElement(new Integer(1));
- }
- else if(gameAction == DOWN)
- {
- mySnakeMc.kbq.addElement(new Integer(3));
- }
- }
- return;
- }
- /**
- * Clear the game screen
- */
- private void clear(Graphics g) {
- g.setColor(0xFFFFFF);
- g.fillRect(0, 0, getWidth(), getHeight());
- }
- /**
- * Paint the game screen
- */
- public void paint(Graphics g) {
- g.setFont(font);
- synchronized (g) {
- /*
- * Clear the screen
- */
- clear(g);
- /*
- * Paint the Snake and Food
- */
- synchronized (SnakeGame.this.repaintLock)
- {
- g.setColor(0x2000ff);
- for(int i=0;i<mySnakeMc.food.size();i++)
- {
- SnakeBlock s = (SnakeBlock)mySnakeMc.food.elementAt(i);
- g.fillRect(s.x, s.y, mySnakeMc.blocksize-1,
- mySnakeMc.blocksize-1);
- }
- g.setColor(0x007fff);
- for(int i=0;i<mySnakeMc.sa.size();i++)
- {
- SnakeBlock s = (SnakeBlock)mySnakeMc.sa.elementAt(i);
- g.fillRect(s.x, s.y, mySnakeMc.blocksize-1,
- mySnakeMc.blocksize-1);
- }
- }
- g.setColor(0xff6000);
- /*
- * Draw a line in the top of the canvas
- */
- String szInfo = "1P[DANY] "+
- "时间: "+mySnakeMc.tickcount*GAME_SPEED/1000+
- " 得分: "+mySnakeMc.scores;
- g.drawString(szInfo, 0, 0,
- Graphics.LEFT | Graphics.TOP);
- }
- }
- }
- /**
- * The ball thread
- */
- class SnakeMc extends Thread {
- public int StartX = 0;
- public int StartY = 0;
- public int blocksize = 8;
- public int blWidth = 64;
- public int blHeight = 32;
- public int numFood = 5;
- public TextField t = null;
- public TextField t2 = null;
- public SnakeBlock ss = null;
- public Vector sa = new Vector();
- public Vector kbq = new Vector();
- public Vector rr = new Vector();
- public Vector food = new Vector();
- public int scores = 0;
- public int bonus = 0;
- public long tickcount = 0;
- /**
- * Create a Snake Game
- */
- public SnakeMc() {
- setUp();
- }
- /**
- * Set starting position
- */
- void setUp() {
- blWidth = mainFrame.getWidth()/blocksize;
- blHeight = mainFrame.getHeight()/blocksize;
- }
- public SnakeBlock CreateSprite(int w)
- {
- SnakeBlock s = new SnakeBlock();
- return s;
- }
- public SnakeBlock AppendSprite(int w)
- {
- SnakeBlock s = CreateSprite(w);
- sa.addElement(s);
- if(sa.size()>1)
- {
- SnakeBlock pres = (SnakeBlock)sa.elementAt(sa.size()-2);
- s.x = pres.x;
- s.y = pres.y;
- s.xx = pres.xx;
- s.yy = pres.yy;
- s.r = (pres.r+2)%4;
- UpdateSnakePos(s);
- s.r = pres.r;
- }
- else
- {
- s.x = StartX;
- s.y = StartY;
- s.xx = s.x/blocksize;
- s.yy = s.y/blocksize;
- }
- return s;
- }
- public void UpdateSnakePos(SnakeBlock s)
- {
- {
- switch(s.r)
- {
- case 0:
- s.x -= blocksize;
- s.xx--;
- break;
- case 1:
- s.y -= blocksize;
- s.yy--;
- break;
- case 2:
- s.x += blocksize;
- s.xx++;
- break;
- case 3:
- s.y += blocksize;
- s.yy++;
- break;
- }
- }
- }
- public void upateSnakesPos()
- {
- int i = 0;
- for(i = 0;i<sa.size();i++)
- {
- SnakeBlock s = (SnakeBlock)sa.elementAt(i);
- for(int j = 0;j<rr.size();j++)
- {
- int vtmp =((Integer)rr.elementAt(j)).intValue();
- if(i == (vtmp>>16))
- {
- s.r = vtmp%4;
- }
- }
- UpdateSnakePos(s);
- }
- Vector tt = new Vector();
- for(i = 0;i<rr.size();i++)
- {
- int vi =((Integer)rr.elementAt(i)).intValue();
- int tmp = (vi>>16);
- if(tmp <sa.size()+10)
- {
- tt.addElement(new Integer(((tmp+1)<<16)|(vi&0xffff)));
- }
- }
- rr = null;
- rr = tt;
- }
- public void startGame()
- {
- tickcount++;
- if(ss==null)
- {
- tickcount++;
- cleanup();
- ss = AppendSprite(0);
- genFood();
- }
- }
- public boolean IntersectSnake(int xx, int yy)
- {
- int i = 0;
- for(i = 0;i<sa.size();i++)
- {
- SnakeBlock s = (SnakeBlock)sa.elementAt(i);
- if(xx == s.xx && yy == s.yy)
- {
- return true;
- }
- }
- return false;
- }
- public boolean IsGameOver()
- {
- if(ss.xx<0 || ss.xx >blWidth-1 || ss.yy<0 || ss.yy >blHeight-1)
- {
- return true;
- }
- int i = 0;
- for(i = 1;i<sa.size();i++)
- {
- SnakeBlock s = (SnakeBlock)sa.elementAt(i);
- if(ss.xx == s.xx && ss.yy == s.yy)
- {
- return true;
- }
- }
- return false;
- }
- public SnakeBlock getFood(int xx,int yy)
- {
- for(int i = 0;i<food.size();i++)
- {
- SnakeBlock s = (SnakeBlock)food.elementAt(i);
- if(s.xx == xx && s.yy == yy)
- {
- return s;
- }
- }
- return null;
- }
- public void genFood()
- {
- if(food.size()!= 0)
- return;
- int ii=0;
- for(;food.size() <numFood;ii++)
- {
- Random random = new Random();
- int k = random.nextInt();
- int xx = Math.abs(k % blWidth);
- k = random.nextInt();
- int yy = Math.abs(k % blHeight); ;
- if(getFood(xx,yy) == null &&!IntersectSnake(xx,yy) )
- {
- SnakeBlock s = CreateSprite(1);
- s.x = xx*blocksize;
- s.y = yy*blocksize;
- s.xx = xx;
- s.yy = yy;
- food.addElement(s);
- }
- }
- }
- public void eatFood()
- {
- if(ss!= null)
- {
- for(int i = 0;i<food.size();i++)
- {
- SnakeBlock s = (SnakeBlock)food.elementAt(i);
- if(s.xx == ss.xx && s.yy == ss.yy)
- {
- AppendSprite(0);
- if(sa.size()>2)
- {
- bonus += 4*(sa.size()-2);
- if(tickcount>0)
- {
- bonus += sa.size()/tickcount;
- }
- }
- scores += 10+bonus;
- food.removeElementAt(i);
- synchronized (SnakeGame.this.playSoundLock)
- {
- playSound++;
- }
- return;
- }
- }
- }
- }
- public void cleanup()
- {
- sa.removeAllElements();
- food.removeAllElements();
- rr.removeAllElements();
- kbq.removeAllElements();
- ss = null;
- scores = 0;
- bonus = 0;
- tickcount = 0;
- }
- public void GameFrame()
- {
- if(ss!= null)
- {
- tickcount++;
- if(kbq.size()>0)
- {
- int c = 0;
- c = ((Integer)kbq.elementAt(0)).intValue(); // pick the next turn in the queue (may be undefined if queue is empty)
- kbq.removeElementAt(0);
- // and check that it is not undefined and not a 180 degree turn
- // (annoying to be able to turn into the snake with one key press)
- //
- if (c%2!= ss.r%2)
- {
- rr.addElement(new Integer(c)); // change current direction to the new value
- }
- }
- upateSnakesPos();
- if(IsGameOver())
- {
- SnakeGame.this.gameOver = true;
- ss = null;
- return;
- }
- eatFood();
- genFood();
- }
- }
- /**
- * Loop to run thread, loops until game over
- */
- public void run() {
- startGame();
- while (!gameOver) {
- /*
- * Sleep for animation delay
- */
- try {
- Thread.sleep(GAME_SPEED);
- } catch (Exception e) {
- return;
- }
- synchronized (SnakeGame.this.repaintLock) {
- GameFrame();
- mainFrame.repaint(0,0,mainFrame.getWidth(),mainFrame.getHeight());
- }
- }
- /*
- * Get statistic information
- */
- elapsedTime = System.currentTimeMillis()
- - elapsedTime;
- numGames++;
- statsScreen.append(new StringItem("Game " +
- numGames + " over", "时间: " +
- (elapsedTime/1000) + " 秒 " +
- "得分: "+scores
- ));
- /*
- * Show the statistics screen
- */
- myDisplay.setCurrent(statsScreen);
- }
- }
- class SoundPlayer extends Thread {
- Player myPlayer = null;
- public SoundPlayer()
- {
- try {
- InputStream is = getClass().getResourceAsStream("/audio/recycle.wav");
- myPlayer =Manager.createPlayer(is,"audio/x-wav");
- } catch (MediaException pe) {
- } catch (IOException ioe) {
- }
- }
- public void run() {
- while (!gameOver) {
- try {
- Thread.sleep(5);
- } catch (Exception e) {
- return;
- }
- int num=0;
- synchronized (SnakeGame.this.playSoundLock)
- {
- num =playSound;
- playSound=0;
- }
- for(int i=0;i<num;i++)
- {
- try {
- myPlayer.start();
- } catch (MediaException pe) {
- }
- }
- }
- }
- }
- }
Step9.运行D:/makeSnakeEM3.bat,编译生成snake.jar.
Step10.运行C:/Motorola/5.4.2/launchpad.exe,选择D:/com/snake/snake.jad,Launch运行测试.
Step11.使用Usb线把D:/com/snake/snake.jar复制到手机(我使用的型号是e680i)上.
Step12.在手机运行snake.jar,提示安装,按提示安装完毕,在程序菜单中运行游戏.
Step13.结束. :)