/*
* GameCanvas.java
*
* Copyright 2001 SkyArts. All Rights Reserved.
*/
import javax.microedition.lcdui.*;
import java.util.*;
/**
* 游戏的描绘与操作所用的类
*
*/
class GameCanvas extends Canvas implements Runnable, CommandListener {
/** 储存横向长度的变量 */
private int screenWidth;
/** 储存纵向长度的变量 */
private int screenHeight;
/** 储存SpaceShooter对象的变量 */
private SpaceShooter spaceShooter;
/** 储存使用在标题之图像的变量 */
private Image titleImg;
private Image backImg;
/** 储存自机类别之对象的变量 */
private MyShip myShip = new MyShip();
// 储存自机飞弹类别之对象的数组变量,飞机炮弹数量的上限
private Vector myMissiles=new Vector();
/** 储存自机之飞弹发射数的变量 */
private int myMissileCount;
/** 储存了UFO类别之对象的数组变量 */
Vector ufos=new Vector();
/** 储存了UFO使用数 */
private int ufoCount;
//储存了所有UFO所有的子弹
private UFOMissile[] ufoMissiles = new UFOMissile[] {
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile(),
new UFOMissile()
};
/** 储存了UFO之飞弹发射数的变量 */
private int ufoMissileCount;
/** 用来储存描绘的间隔(INTERVAL)的常量 */
private static long DRAW_INTERVAL = 100;
/** 显示暂停状态的标志 */
private boolean isPaused;
private boolean isGameFaile=false;
/** 代表游戏循环停止的变量 */
private boolean isStopped;
//private boolean isGameFaile=false;
//存储调用那个函数的次数
private int tickCount4UFO;
private int defaultTick=5;
/** 用来改变UFO的出现之Random变量 */
private Random random = new Random();
/** Start指令变量 */
private Command startCmd = new Command("Start", Command.SCREEN, 5);//一个 label(标号)、一个 type(类型)和一个 priority(优先级)
/** Exit指令变量 */
private Command exitCmd = new Command("Exit", Command.SCREEN, 1);
/** Pause指令变量 */
private Command pauseCmd = new Command("Pause", Command.SCREEN, 5);
/** Resume指令变量 */
private Command resumeCmd = new Command("Resume", Command.SCREEN, 5);
/** Quit指令变量 */
private Command quitCmd = new Command("Quit", Command.SCREEN, 1);
/** 储存分数的变量 */
private long score =0;
/** 储存最高分数的变量 */
private long highScore = 0;
private long lastlevelscore=0;
/** 用来储存默认分数的常量 */
private static final long DEFAULT_SCORE = 100;
/** 储存生命点数的变量 */
private int lives;
private int level=1;
/** 用来储存默认之生命点数的常量 */
private static final int DEFAULT_LIVES = 3;
/** 储存默认字体的变量 */
private Font defFont = Font.getDefaultFont();
/** 储存分数显示部分之高度的常量(设定到默认字体高度) */
private static final int SCORE_AREA = Font.getDefaultFont().getHeight();
/** 代表标题显示状态的常量 */
private static final short TITLE = 0;
/** 代表游戏开始显示状态的常量 */
private static final short GAME_START = 1;
/** 代表游戏中显示状态的常量 */
private static final short GAME_PLAYING = 2;
/** 代表游戏结束显示状态的常量 */
private static final short GAME_END = 5;
private static final short GAME_WIN =6;
/** 储存现在显示状态的变量 */
private short gameState;
//private playMusic playmusic=new playMusic();
/** 构造函数 */
GameCanvas(SpaceShooter spaceShooter) {
this.spaceShooter = spaceShooter;
//取得画面的可描绘范围
screenWidth = getWidth();
screenHeight = getHeight();
//初始化UFO的个数
for(int i=0;i<4;i++){
ufos.addElement(new UFO(myShip));
}
//初始化我机子弹的个数
for(int i=0;i<8;i++)
{
myMissiles.addElement(new MyMissile());
}
//取得标题图像
try {
titleImg = Image.createImage("/title.png");
backImg=Image.createImage("/earth.png");
}catch(Exception e) {}
//登录指令监听
setCommandListener(this);
//将游戏的状态变成显示标题
gameState = TITLE;
}
/** 进行游戏之初始化的方法 */
private void doGameInit() {
level=1;
//清除分数
score =lastlevelscore;
//将自机的位置设定于中央
myShip.setX((screenWidth - myShip.getWidth()) /2);
myShip.setY(screenHeight - myShip.getHeight());
myShip.setHit(false);//清除Hit状态
//将生命点数设为默认值
lives = DEFAULT_LIVES;
//清除自机飞弹
for(int i=0; i < myMissiles.size(); i++) {
MyMissile m1=(MyMissile)myMissiles.elementAt(i);
m1.setAlive(false);
myMissiles.setElementAt(m1,i);
}
//清除自机飞弹数
myMissileCount = 0;
//清除UFO
for(int i=0; i < ufos.size(); i++) {
UFO temp=(UFO)ufos.elementAt(i);
temp.setAlive(false);
ufos.setElementAt(temp,i);
}
//清除UFO数
ufoCount = 0;
//清除UFO飞弹
for(int i=0; i < ufoMissiles.length; i++) {
ufoMissiles[i].setAlive(false);
}
//清除UFO飞弹数
ufoMissileCount = 0;
//清除要让UFO出现时所使用的Tick计数
tickCount4UFO = 0;
//清除游戏循环停止标志
isStopped = false;
//清除暂停标志
isPaused = false;
}
/** MIDlet的startApp()被调用出来时所调用的方法 */
void doStartApp() {
doTitle();
}
/** MIDlet的pauseApp()方法被调用出来时所调用的方法 */
void doPauseApp() {
switch(gameState) {
case TITLE: //显示标题时
break;
default: //上述情形以外时
//暂停
isPaused = true;
//停止游戏循环
isStopped = true;
break;
}
}
/** 进行标题显示的方法 */
private void doTitle() {
//将游戏的状态设为显示标题
gameState = TITLE;
//以防万一先将关卡中的指令删除
removeCommand(pauseCmd);
removeCommand(resumeCmd);
removeCommand(quitCmd);
//显示标题画面
repaint();
//新增指令
addCommand(startCmd);
addCommand(exitCmd);
}
/** 启动描绘线程的方法 */
private void doThreadStart() {
new Thread(this).start();
}
/** 结束游戏的方法 */
private void doGameStop() {
//停止游戏循环
isStopped = true;
//设定最高分数
if(isGameFaile)
{ //恢复到开始时的状态,只有游戏结束时调用。暂停时不会调用
setHighScore(score);
score=0;
lastlevelscore=0;
DRAW_INTERVAL=100;
defaultTick=5;
ufos.removeAllElements();
for(int i=0;i<4;i++)
ufos.addElement(new UFO(myShip));
myMissiles.removeAllElements();
for(int j=0;j<8;j++)
myMissiles.addElement(new MyMissile());
isGameFaile=false;
}
}
/** 进行暂停或是重新开始的方法 */
private void doPauseOrResume() {
if(isPaused) {
//暂停时
//重新开始
isPaused = false;
isStopped = false;
doThreadStart();
}else {
//不是暂停时
//暂停
isPaused = true;
doGameStop();
}// end if
repaint();
}
/**
* 进行描绘的方法,通常不会从自类别来调用
* @param g Graphics对象
*/
protected void paint(Graphics g) {
//清屏
g.setColor(0x00000000);
g.fillRect(0, 0, screenWidth, screenHeight);
g.setFont(defFont);
String drawSt;
int drawX, drawY, stWidth;
int stHeight = defFont.getHeight();
//根据游戏状态来改变描绘内容
switch(gameState) {
case TITLE://显示标题时
//描绘标题图像
drawX = (screenWidth - titleImg.getWidth()) /2;
g.drawImage(titleImg, drawX, 0, Graphics.TOP|Graphics.LEFT);
//显示最高分数
g.setColor(0x00FFFFFF);
g.setFont(defFont);
drawSt = "最高分数";
drawX = (screenWidth - defFont.stringWidth(drawSt)) / 2;
drawY = titleImg.getHeight()-5;
g.drawString(drawSt, drawX, drawY, Graphics.TOP|Graphics.LEFT);
drawX = drawX + defFont.stringWidth(drawSt) - defFont.stringWidth(String.valueOf(highScore));
drawY = drawY+ stHeight;
g.drawString(String.valueOf(highScore), drawX, drawY, Graphics.TOP|Graphics.LEFT);
//显示着作权
drawSt = "Copyright 2008";
drawX = (screenWidth - defFont.stringWidth(drawSt)) / 2;
drawY = getHeight() - stHeight *2;