做好了菜单。现在我们该考虑怎么实现直升飞机了。
J2ME已经在javax.microedtion.game.Sprite提供了专门的精灵类
Sprite类继承自javax.microedtion.game.layer,而如前文所述,layer是游戏画面绘制的重要元素.
Sprite类有以下几个常用的方法(显然从字面上就能知道这些方法是做什么的):
move(int x,int y);
setPosition(int x,int y);
setVisible();
paint(Graphics g);
但实际上不是特别方便实用,我们必须得每次指定如何更新帧,同时这个类仅仅表示了一组帧而已,我们需要更多的功能,这里我引用了网上一篇教程中的东西,(来源:http://www.yesky.com/370/1871370.shtml作者:favoyang )
一个封装了Sprite的GameObject类;
public class GameObject {
public Sprite sprite;//内置的Sprite
public boolean alive;//存活标记
private int lifecount=0;//生命周期计数器
public int lifetime=0;//生命周期,以桢为单位
public int speed=0;//动画桢更新速度,(0至无穷,0代表每一桢跟新一个画面)
private int animcount=0;// /动画桢更新计数器
public GameObject(Image img,int width,int height){
sprite=new Sprite(img,width,height);
reset();
}
public void move(int dx,int dy){//相对移动
sprite.move(dx,dy);
}
public void moveto(int x,int y){//绝对移动
sprite.setPosition(x,y);
}
public void update(){//更新状态,动画桢更新,生命周期更新
if(!alive)
return;
if(++animcount>speed){
animcount=0;
sprite.nextFrame();
if(lifetime!=0 && ++lifecount>lifetime)
alive=false;
}
}
public void paint(Graphics g){//Paint
if(!alive)
return;
sprite.paint(g);
}
public void reset(){//复位
alive=true;
lifecount=0;
animcount=0;
sprite.setFrame(0);
}
}
可以明显感觉到这个类比Sprite类的进步,我们可以控制它的生命周期,而不是要去一帧一帧的调整,更可方便地设置GameObject中Sprite的更新速度.
在我这个游戏里直升飞机是个复杂的运动体:螺旋桨在旋转,机身不做变化.所以我用一个Helicopter类封装了两个GameObject,一个GameObject 叫 heliBody(机身),另一个叫heliScrew(螺旋桨) .同时,还有一个额外的部分,
GameObject exploit,用于在飞机坠毁后显示爆炸效果.
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.io.*;
public class Helicopter {
public boolean alive; // 飞机是否存活,如果dying == true,依然认为飞机还存活
private GameObject heliBody = null;
private GameObject heliScrew = null;
private GameObject exploit = null;
private Image img;
private Rect playerRect = null; //自定义的Rect类,用来传送当前单元所占的空间范围.
public boolean dying = false; // 指示飞机是不是处在爆炸过程中
public Helicopter() {
alive = true;
try {
img = Image.createImage("/res/helicopter.png");
}
catch (IOException ioe){
ioe.printStackTrace();
}
heliBody = new GameObject(img,12,28);
heliBody.lifetime = 1;
try{
img = Image.createImage("/res/screws.png");
}catch (IOException ioe){
ioe.printStackTrace();
}
heliScrew = new GameObject(img,8,24);
heliScrew.lifetime = 7;
img = null;
try {
img = Image.createImage("/res/exploit.png");
}catch(IOException ioe){
ioe.printStackTrace();
}
exploit = new GameObject(img,30,30);
exploit.lifetime = 4; // 爆炸效果有 4 帧
exploit.speed = 1;
playerRect = new Rect(0,0,0,0);
}
public void update(){
if(dying == true){
if(exploit.alive == true)exploit.update(); // 如果是dying则更新爆炸效果
else alive = false; // 爆炸结束后飞机生命结束
return;
}
if(heliScrew.alive == true)heliScrew.update(); //正常情况下,循环更新螺旋桨,使其不停转动
else heliScrew.reset();
}
public void moveto(int x,int y){ // 移动飞机位置,在按键处理中会调用
playerRect.top = y;
playerRect.left = x;
playerRect.right = x + 16;
playerRect.bottom = y + 34; /// 调整飞机所占空间范围
exploit.moveto(x,y);
heliScrew.moveto(x,y);
heliBody.moveto(x+4,y+6);
}
public void paint(Graphics g){ /// 绘图
if(dying == true && alive == true){
exploit.paint(g);
return;
}
if (!alive)
return;
heliBody.paint(g);
heliScrew.paint(g);
}
public Rect getPlayerRect(){ /// 范围飞机位置范围,在碰撞检测中会用到
return playerRect;
}
}