折腾了近1个月的NOKIA开发环境,脑袋里已经全是屎了。遂决定去厕所拉了个干净,把池子都砸坏了……
闲话少叙,现在的状况是已经返朴归真用记事本做程序了。编译方面直接用新下载的Wireless Tools Kit 2.2,以及它自带的KToolBar来创建和开发我的游戏。
WTK不需要烦琐的环境设置,点创建项目,输好工程名称,再设置一下MIDP和CLDC再点完成就成了。然后就是打开一个记事本,编好程序存成.java格式的程序文件就可以了。用记事本编程序有个好处,就是每次打开开发环境、调整代码和编译的时候速度快的要死,根本不用等着我的破本儿滋扭滋扭的转它衰老的硬盘。
总之,先把代码贴出来吧,后面我会一一讲解:
// UFOMIDlet.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class UFOMIDlet extends MIDlet implements CommandListener {
private UFOCanvas canvas;
public void startApp() {
if (canvas == null) {
canvas = new UFOCanvas(Display.getDisplay(this));
Command exitCommand = new Command("Exit", Command.EXIT, 0);
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
}
canvas.start();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {
canvas.stop();
}
public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT) {
destroyApp(true);
notifyDestroyed();
}
}
}
// UFOCanvas.java
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;
import java.util.*;
import java.io.*;
public class UFOCanvas extends GameCanvas implements Runnable {
private Display display;
private boolean sleeping, restart;
private long frameDelay;
private Random rand;
private Sprite ufoSprite;
private Sprite gameoverImg, coverImg;
private int ufoXSpeed, ufoYSpeed;
private int ox = 0, oy = 0;
private int gx = -getWidth(), gy = -getHeight();
private int cx, cy, sx, sy;
private int score;
private int ufoLife = 3;
private Sprite[] roidSprite = new Sprite[3];
private Sprite[] ufolifeSprite = new Sprite[3];
public UFOCanvas(Display d) {
super(true);
display = d;
frameDelay = 33;
}
public void start() {
display.setCurrent(this);
rand = new Random();
ufoXSpeed = ufoYSpeed = 0;
restart = true;
score = 0;
try {
//初始化UFO、游戏结束画面、封面画面、玩法介绍画面、关于我们画面的精灵和位置
ufoSprite = new Sprite(Image.createImage("/Saucer.png"));
ufoSprite.setPosition((getWidth() - ufoSprite.getWidth()) / 2,
(getHeight() - ufoSprite.getHeight()) / 2);
gameoverImg = new Sprite(Image.createImage("/gameover.png"));
gameoverImg.setPosition(-getWidth(),-getHeight());
coverImg = new Sprite(Image.createImage("/cover.png"));
coverImg.setPosition(0,0);
//初始化小行星精灵和位置和动画侦范围
Image img = Image.createImage("/Roid.png");
roidSprite[0] = new Sprite(img, 42, 35);
roidSprite[1] = new Sprite(img, 42, 35);
roidSprite[2] = new Sprite(img, 42, 35);
//初始化UFO生命图示精灵和位置
Image img2 = Image.createImage("/UFO.png");
ufolifeSprite[0] = new Sprite(img2,12,12);
ufolifeSprite[0].setPosition(2,270);
ufolifeSprite[1] = new Sprite(img2,12,12);
ufolifeSprite[1].setPosition(14,270);
ufolifeSprite[2] = new Sprite(img2,12,12);
ufolifeSprite[2].setPosition(26,270);
}catch (IOException e) {}
//开始线程
sleeping = false;
Thread t = new Thread(this);
t.start();
}
public void stop() {
//结束的时候把显示分值置于屏幕中央
sx = getWidth()/2;
sy = getHeight()/2;
sleeping = true;}
public void run() {
Graphics g = getGraphics();
//游戏主循环
while (!sleeping) {
update();
draw(g);
try {
Thread.sleep(frameDelay);
}catch (InterruptedException ie) {}
} //while
} //run
private void update() {
//用restart来判断是否显示主画面还是进入游戏
if(restart) {
int keyState = getKeyStates();
if((keyState & FIRE_PRESSED)!= 0) {
coverImg.setPosition(-getWidth(),-getHeight());
restart = false;
score = 0;
}
else coverImg.setPosition(0,0);
return;
}
//通过按上下左右键来改变精灵速度
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0)
ufoXSpeed--;
else if ((keyState & RIGHT_PRESSED) != 0)
ufoXSpeed++;
if ((keyState & UP_PRESSED) != 0)
ufoYSpeed--;
else if ((keyState & DOWN_PRESSED) != 0)
ufoYSpeed++;
//UFO速度在8和-8之间随机取得
ufoXSpeed = Math.min(Math.max(ufoXSpeed, -8), 8);
ufoYSpeed = Math.min(Math.max(ufoYSpeed, -8), 8);
ufoSprite.move(ufoXSpeed, ufoYSpeed);
checkBounds(ufoSprite);
for (int i = 0; i < 3; i++) {
roidSprite[i].move(i + 1, 1 - i); //使三个小行星向不同的方向运动
checkBounds(roidSprite[i]); //折屏算法
//第二个小行星精灵roidSprite[1]是反向侦动画,否则是正向侦动画
if (i == 1)
roidSprite[i].prevFrame();
else
roidSprite[i].nextFrame();
// 检测碰撞
if (ufoSprite.collidesWith(roidSprite[i], true)) {
// 播放警告声音
AlertType.ERROR.playSound(display);
// 碰撞之后重置UFO精灵和移动速度
ufoSprite.setPosition((getWidth() - ufoSprite.getWidth()) / 2,
(getHeight() - ufoSprite.getHeight()) / 2);
ufoXSpeed = ufoYSpeed = 0;
//重置小行星位置
for (int j = 0; j < 3; j++)
roidSprite[j].setPosition(0, 0);
//UFO生命减少并停止游戏
if ( ufoLife > 0 ) {
ufoLife--;
ufolifeSprite[ufoLife].setPosition(-12,-12);
}
else {
gameoverImg.setPosition(0,0);
for (int j = 0; j < 3; j++)
roidSprite[j].setPosition(-43, -35); //将小行星置于屏幕外
stop();
}
// 此时不用更新小行星精灵
break;
}
//检测得分
for(int l = 0; l < 3; l++) {
if (Math.abs(ufoSprite.getX() - roidSprite[l].getX()) < 22 &&
Math.abs(ufoSprite.getY() - roidSprite[l].getY()) < 22) {
AlertType.WARNING.playSound(display);
gx = getWidth()/2;
gy = getHeight()/2;
score += 5;
}
}
}
}
//绘画所有的要素,顺序很重要——它决定了谁遮盖住谁
private void draw(Graphics g) {
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(255, 255, 255); // white
g.drawString("You 've touched :"+score,sx, sy, Graphics.TOP | Graphics.LEFT);
g.drawString("Good!", gx, gy, Graphics.TOP | Graphics.HCENTER);
ufoSprite.paint(g);
gameoverImg.paint(g);
for (int i = 0; i < 3; i++)
roidSprite[i].paint(g);
for (int k = 0; k < 3; k++)
ufolifeSprite[k].paint(g);
coverImg.paint(g);
flushGraphics();
}
//折屏算法
private void checkBounds(Sprite sprite) {
if (sprite.getX() < -sprite.getWidth())
sprite.setPosition(getWidth(), sprite.getY());
else if (sprite.getX() > getWidth())
sprite.setPosition(-sprite.getWidth(), sprite.getY());
if (sprite.getY() < -sprite.getHeight())
sprite.setPosition(sprite.getX(), getHeight());
else if (sprite.getY() > getHeight())
sprite.setPosition(sprite.getX(), -sprite.getHeight());
} //checkBounds
} //UFOCanvas