import java.util.Random;
import java.util.Vector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
/**
*
* @author WangJing
* 本类继承了GameCanvas,用以处理游戏中的显示、逻辑处理和输入处理等。
* 类中用到了层管理器和精灵。
*/
public class GameScreen extends GameCanvas
implements Runnable, CommandListener {
/////////////////////////玩家精灵的相关变量和常量//////////////////////////////////////
/*
*游戏屏幕中的玩家的精灵
*/
private PlayerSprite player;
/**
* 玩家精灵的精灵图片的宽度常量
*/
private static int FRAME_WIDTH = 32;
/**
* 玩家精灵的精灵图片的高度常量
*/
private static int FRAME_HEIGHT = 32;
/**
* 游戏屏幕的宽度
*/
private int scnWidth;
/**
* 游戏屏幕的高度
*/
private int scnHeight;
/**
*玩家的子弹容器,用以保存玩家发射出的子弹。
*/
private Vector playerBullets;
/**
* 玩家图片
*/
private Image playerImage = getImage("/player.png");
/**
* 子弹图片
*/
private Image bulletImage = getImage("/bullet.png");
////////////////////////--玩家精灵的相关变量和常量--///////////////////////////////////
////////////////////////游戏中敌人相关的变量和常量////////////////////////////////////
/**
* 游戏中敌人的个数常量
*/
private byte ENIMY_NUMBER = 4;
/**
* 敌人发射子弹的计时常量
*/
private byte COUNT_PER_BULLET = 20;
/**
* 敌人移动的计数常量
*/
private byte COUNT_PER_MOVE = 5;
/**
* 游戏中敌人精灵数组
*/
Sprite[] enimy = new Sprite[ENIMY_NUMBER];
/**
* 保存敌人子弹的向量容器
*/
Vector enimyBullets;
/**
* 当敌人发射子弹时,只有当count = 0时才能发射,然后再让count=COUNT_PER_BULLET,每次执行
* ticker()函数时,减1,这样可以控制敌人的子弹速度
*/
private byte countForShot = COUNT_PER_BULLET;
/**
* 敌人的是否向右移动的状态。
*/
private boolean[] isMoveRightState = new boolean[ENIMY_NUMBER];
/**
* 初始为COUNT_PER_MOVE,没执行一次ticker()函数,减一,如果这个变量为0,那么就开始移动,
* 然后这个变量变为COUNT_PER_MOVE。继续如此。
*/
private byte countForMove = COUNT_PER_MOVE;
private boolean[] enimyDeathState = {false,false,false,false};
////////////////////////--游戏中敌人相关的变量和常量--////////////////////////////////////
///////////////////////总体的游戏屏幕中相关的变量和常量////////////////////////////////////
private short MILLS_PER_TICK = 50;
/**
* 层管理器。管理图层。
*/
LayerManager layerManager;
/**
* 地形的贴图层,用于处理地形。
*/
TiledLayer terrain;
/**
* 地形滚动的变量。这个变量用来标记地形的y值。
*/
int terrainScorll;
/**
* 游戏线程。
*/
Thread gameThread;
public static byte PLAY_STATE = 1;
public static byte SUCCESS_STATE = 2;
public static byte RESTART_STATE = 3;
public static byte FAILED_STATE = 4;
public static byte ALLPASS_STATE = 5;
public static byte PAUSE_STATE = 6;
public byte currentState = PAUSE_STATE;
/**
* 游戏是否开始
*/
private boolean isPlay = false;
/**
* 游戏是否已经成功
*/
private boolean isSuccessState = false;
/**
* 游戏是否失败
*/
private boolean isFaiedState = false;
/**
* 记录游戏的分数
*/
private int score;
/**
* 退出按钮的命令
*/
private Command backCommand = new Command("退出", Command.BACK, 1);
/**
* 开始按钮的命令
*/
private Command startCommand = new Command("开始", Command.OK, 1);
/**
* 暂停按钮的命令
*/
private Command pauseCommand = new Command("暂停", Command.CANCEL, 1);
/**
* 继续的按钮
*/
private Command continueCommand = new Command("继续", Command.OK, 1);
/**
* 重新开始的按钮
*/
private Command restartCommand = new Command("重新开始", Command.OK, 1);
/**
* MIDlet的引用
*/
private MainMidlet mainMidlet;
/**
* 当前的关卡级别
*/
private int currentLevel = 0;
///////////////////////--总体的游戏屏幕中相关的变量和常量--///////////////////////////////
/**
* 返回图片类的实例
* @param 图片所在的路径
* @return 图片类的对象
* @throws java.lang.Exception 当路径错误时,抛出此异常
*/
public static Image getImage(String filename) throws Exception {
Image image = null;
image = Image.createImage(filename);
return image;
}
/**
* 游戏屏幕类的构造函数,首先继承了父类GameCanvas的构造方法。并在这里面对变量进行初始化。
* @param b 父类构造函数中用到的构造函数
* @throws java.lang.Exception 当创建图片出错时,抛出此异常
*/
public GameScreen(boolean b, MainMidlet mainMidlet) throws Exception {
super(b);
this.mainMidlet = mainMidlet;
this.addCommand(backCommand);
this.addCommand(startCommand);
this.setFullScreenMode(true);
setCommandListener(this);
scnWidth = this.getWidth();
scnHeight = this.getHeight();
init(1);//调用初始化函数,初始化等级为1
this.render(this.getGraphics());
}
/**
* 初始化地形(贴图层的对象)变量。
* @throws java.lang.Exception 当创建地形时,要到的图片错误时,抛出此异常
*/
public void initTerrain() throws Exception {
//地图的二维表示
int[][] map1 = {
{0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0},
{3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0},
{3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3},
{3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3},
{3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3},
{3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3}, {0, 0, 0, 0, 0, 0}, {3, 0, 0, 0, 0, 0}, {3, 3, 3, 3, 3, 3},
};
//初始化地形贴图层
terrain = new TiledLayer(6, 30, getImage("/init.png"), 32, 32);
for (int i = 0; i < 30; i++) {
for (int j = 0; j < 6; j++) {
terrain.setCell(j, i, map1[i][j]);
}
}
//用于设置地形在屏幕坐标系中的位置。地形的位置设置为
//(0,-(地形高-屏幕的高)),这样使屏幕里刚好显示地形的最下方
terrainScorll = 1 - (terrain.getCellHeight() * terrain.getRows()) + scnHeight;
terrain.setPosition(0, terrainScorll);
}
/**
* 初始化函数。当提供级别时,即可对相应关的各个状态进行初始化
* @param level 要初始化所