您的位置:首页 > 其它

J2ME手机游戏贪吃蛇开发Step By Step

2008-09-21 17:15 337 查看
呵呵,昨天晚上开始学习手机游戏编写,现在现学现卖,希望可以帮到一些初手.:).

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.结束. :)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: