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.结束. :)
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.结束. :)
相关文章推荐
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--贪吃蛇_1
- FLEX ActionScript 游戏开发教程之[贪吃蛇]Step By Step
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--贪吃蛇
- 小例子学J2ME手机游戏开发--(一)初具手机游戏框架的HelloWorld
- J2ME专业手机游戏开发基础
- JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_3_增加成绩记录
- j2me手机游戏编程第一课(开发环境搭建和第一个MIDlet程序 视频)
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--扫雷(3)-带线程--仿windows扫雷
- 使用J2ME技术开发《贪吃蛇》游戏(已在《软件报》发表,严禁转载)
- 用Eclipse开发J2ME手机游戏 第四讲 创建经典的HelloWorld程序
- 2005年毕业论文----J2ME手机游戏开发高计
- J2ME手机游戏开发中位运算的用处
- JAVA游戏编程之二----j2me MIDlet 手机游戏入门开发--扫雷(2)-不含线程
- JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_5_使用LUA脚本写游戏
- 2005年毕业论文----J2ME手机游戏开发高计
- J2ME开发手机游戏物理模型之抛物线
- 用Eclipse开发J2ME手机游戏入门(环境安装)
- J2ME专业手机游戏开发基础(1)
- j2me游戏开发之手机键值
- 用Eclipse开发J2ME手机游戏入门(创建Hello)》