2.游戏入口MIDlet类TankWar
TankWar类是游戏的入口,玩家刚进入游戏时所显示的画面、游戏说明以及退出整个应用程序都必须经过该类实现,运行界面见图4,关键代码如下。
protected void startApp() throws MIDletStateChangeException {//初始化界面
try {
tankimg = Image.createImage("/tankimg.png");
} catch (IOException e) {
e.printStackTrace();
}
form = new Form("TANK_WAR");
form.addCommand(okCommand);
form.addCommand(msgCommand);
form.addCommand(exitCommand);
form.append(tankimg);
form.setCommandListener(this);
display.setCurrent(form);
}
public void commandAction(Command c, Displayable arg1)
{ //菜单处理
if(c==exitCommand){
destroyApp(true);notifyDestroyed();
}
else if(c==okCommand){
TankGameCanvas gameCanvas = new TankGameCanvas(this);
gameCanvas.start();
display.setCurrent(gameCanvas);
}
else if(c==msgCommand){
Form form = new Form("游戏说明");
form.append("本游戏采用J2ME技术,利用传统FC机上的游戏进行重新设计," +
"以求在内容上和玩法上都有更好创新!本游戏操作方法如下:" +
"方向杆控制玩家主坦克行走方向,数字键2对应方向向上,数字键8对" +
"应方向向下,数字键4对应方向向左,数字键6对应方向向右,数字键5为" +"发射子弹。");
form.addCommand(backCommand);
form.setCommandListener(this);
display.setCurrent(form);
}
else if(c==backCommand){
try { startApp();
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
}
}
游戏利用TankGameCanvas线程类实现主循环,由于本游戏对实时控制要求比较严格,主循环里通过一系列函数来控制玩家的输入、检测坦克与障碍物以及坦克与坦克的碰撞、绘制屏幕、AI控制等功能,运行界面见图5。
public void run() {
//获取Grapihics对象
Graphics g = getGraphics();
//游戏主循环
while(isPlay){
input();//玩家输入控制
createWall();//创建堡垒周围围墙
createMTank();//创建玩家坦克
createETank();//创建敌方坦克
createETankBullet();//创建敌方坦克子弹
AILogic();//敌方坦克AI控制
checkCollision();//检测碰撞
//绘制屏幕
drawScreen(g);
//线程运行时间间隔,目前设置间隔为delay=20;
try{
Thread.sleep(delay);
}catch(InterruptedException ie){}
}
}
在MIDP1.0里的Canvas类里获取键盘按键状态时必须实现keyPressed()、keyRelease() 、keyRepeated(),写起来显得相当繁琐。而在MIDP2.0里新增加的GameCanvas类里,如果要检查特定的按键是否被按下,只需要将getKeyStates()返回的值与这些键值进行按位与运算并根据计算结果来判断就可以了。TankGameCanvas线程类控制游戏的关键代码如下:
public void input(){
M_Tank.defineCollisionRectangle(0, 0, 16, 12); //设置主坦克的碰撞区域
int keystates = getKeyStates(); //获取键盘按键状态
int keystate = keystates; //用于控制多个方向键按下时同时发生作用
if((keystate&LEFT_PRESSED)!=0){ //方向键向左按下时的实现
keystate = 0;
setDir(2); //设置并获取主坦克的方向
M_Tank.setTransform(Sprite.TRANS_MIRROR_ROT270); //主坦克方向向左
if(!M_Tank.collidesWith(mBackground, true)){ //与地图障碍物的碰撞检测
curX = Math.max(0,curX-2);} //主坦克横坐标-2,且不小于0
}
if((keystate&RIGHT_PRESSED)!=0){ //方向键向右按下时的实现
keystate = 0;
setDir(3); //设置并获取主坦克的方向
if(!M_Tank.collidesWith(mBackground, true)){ //与地图障碍物的碰撞检测
if(curX+15<238) //不会越界的情况下
curX = Math.min(238,curX+2);} //主坦克横坐标+2,且不超过右边界
M_Tank.setTransform(Sprite.TRANS_ROT90); //主坦克方向向左
}
if((keystate&UP_PRESSED)!=0){
keystate = 0;
setDir(0); //设置并获取主坦克的方向
if(!M_Tank.collidesWith(mBackground, true)){ //与地图障碍物的碰撞检测
curY = Math.max(0,curY-2);} //主坦克纵坐标-2,且不小于0
M_Tank.setTransform(Sprite.TRANS_NONE); //主坦克方向向上
}
if((keystate&DOWN_PRESSED)!=0){ //方向键向下按下时的实现
keystate = 0;
setDir(1); //设置并获取主坦克的方向
if(!M_Tank.collidesWith(mBackground, true)){ //与地图障碍物的碰撞检测
if(curY+26<240)
curY = Math.min(240,curY+2);} //主坦克纵坐标+2,且不超过下边界
M_Tank.setTransform(Sprite.TRANS_MIRROR_ROT180); //主坦克方向向下
}
if((keystates&FIRE_PRESSED)!=0){ //开火按键触发时
createBullet(); //创建子弹
}
}
|