這是很早以前看184規範時寫的小程式,純脆是練手的,因為當時沒做過真機測試,是以效能上肯定不行,代碼也不是很規範,沒寫注釋.整個項目都是跑通的,我在朋友索愛的walkman上測試了下.
現在做app了,遊戲方面,很久沒看了,一句話很讓人省悟,雖然不太願意相信:基于j2me+web的遊戲,是做不出PC平台遊戲的那種輝煌的.(game規模,game界面,響應速度,費用,限制太多太多了,還需要硬體的進一步發展,這個産業才能真正壯大起來)
汗死,CRC校驗錯誤,所有資源檔案都不能用.PNG M3G MAX都失效了,隻有源檔案了,等我回家了再把東西補傳上來吧,大家将就下先湊合下看看源碼吧。
下圖是遊戲截圖:

About.java
//Text "About" code skeleton
import javax.microedition.lcdui.*;
public class About extends Form implements CommandListener
{
//Command for going back to the main menu
private Command back = new Command("Back", Command.BACK, 1);
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
public About(String title,AirFighterMIDlet parent, MainMenu menu)
{
super(title);
this.parent = parent;
this.menu = menu;
this.addCommand(back);
this.append("/n/n/n/n ==== Version 1.0.0 ====/n Legion 2007年作版權所有(C)");
this.setCommandListener(this);
}
public void commandAction(Command p0, Displayable p1)
{
if (p0 == back)
{
parent.setDisplayable(menu);
}
}
}
Aim.java
import java.util.Random;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Loader;
import javax.microedition.m3g.RayIntersection;
public class Aim
{
private float[] pos = {0.0f, 0.0f, 0.0f};
//是否死亡
private boolean life=true;
private int itemID=0;
private Random rand;
private Group goomba;
RayIntersection ri;
public Aim(int itemID,Group group,Random ran)
{
//System.out.println("Create Aim:");
goomba=MeshFactory.createGoomba("/res/goomba.m3g");
// /res/machine.m3g
// /res/goomba.m3g
group.addChild(goomba);
goomba.setUserID(itemID);
setID(itemID);
ri = new RayIntersection();
rand=ran;
setLife(false);
}
public void init(int i,Group group)
{
pos[0] = 15.0f-rand.nextFloat()*30.0f;
pos[2] = 15.0f-rand.nextFloat()*30.0f;
group.pick(-1, pos[0],10.0f, pos[2], 0.0f, -1.0f, 0.0f, ri);
pos[1] = 10.0f-ri.getDistance();
setLife(true);
//System.out.println("Aim "+i+" pos:"+pos[0]+","+pos[1]+","+pos[2]);
//System.out.println();
goomba.translate(pos[0],pos[1],pos[2]);
}
public void setPos(float[] tpos)
{
System.arraycopy(tpos, 0, pos, 0, pos.length);
}
float[] getPos()
{
return pos;
}
void setLife(boolean life)
{
this.life = life;
}
boolean getLife()
{
return life;
}
void setID(int id)
{
itemID = id;
}
int getID()
{
return itemID;
}
}
AimSystem.java
import java.util.Random;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Transform;
public class AimSystem
{
Aim[] aim=null;
int hitnum=0;//記錄擊中數
Transform tran;
Random ran;
public AimSystem(int aimNum,Group group,BulletSystem bs)
{
aim=new Aim[aimNum];
ran=new Random();
tran=new Transform();
tran.setIdentity();
tran.postTranslate(0.0f, 2.0f, 0.0f);
for(int i=0;i<aim.length;i++)
{
aim[i]=new Aim(300+i,group,ran);
//System.out.println("Goomba[i] ID:"+aim[i].getID());
aim[i].init(i,group);
//System.out.print("Bullet "+(i+1)+"init:");
tran.postRotate(45.0f-ran.nextFloat()*90.0f, 1.0f, 0.0f, 0.0f);
tran.postRotate(45.0f-ran.nextFloat()*90.0f, 0.0f, 1.0f, 0.0f);
bs.start(i+1, aim[i].getPos(), tran);
}
}
public void kpbulletsurvive(BulletSystem bs)
{
for(int i=1;i<bs.getBulletnum();i++)
{
if(!bs.getBulletState(i))
{
tran.postRotate(ran.nextFloat()*180.0f, 1.0f, 0.0f, 0.0f);
tran.postRotate(90.0f-ran.nextFloat()*180.0f, 0.0f, 1.0f, 0.0f);
bs.start(i, aim[i-1].getPos(), tran);
}
}
}
public void update(Group group)
{
for(int i=0;i<aim.length;i++)
{
if(!aim[i].getLife())
{
aim[i].init(i,group);
}
else
{
//aim[i].updata(group);
}
}
}
public float[] hit(int itemID)
{
float pos[]=null;
for(int i=0;i<aim.length;i++)
{
if(aim[i].getID()==itemID)
{
hitnum++;
pos=aim[i].getPos();
aim[i].setLife(false);
}
}
return pos;
}
int gethitNum()
{
return hitnum;
}
}
AirFighterCanvas.java
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.m3g.Background;
import javax.microedition.m3g.Camera;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Image2D;
import javax.microedition.m3g.Light;
import javax.microedition.m3g.Transform;
import javax.microedition.m3g.World;
public class AirFighterCanvas extends GameCanvas implements Runnable
{
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
private StarHScroller scroller; // scroll stars on the screen.
private int width;
private int height;
private boolean gamePaused;
//private boolean pxCollides=true;
//private boolean trance = false;
//private long delay;
private World world;
private Group heightmap;
private Graphics g;
private Graphics3D g3;
private AimSystem as;
private Camera cameraog;
private Camera camera;
private FountainEffect fe;
private ParticleSystem ps;
private BulletSystem bs;
private Transform transform;
private Light[] light;
private Background background;
private Image2D image2d;
private Image crossImage;
private float camerapos[] = new float[] {0.0f, 2.0f, 2.0f };
private float[] gettrans;
private float radian = 3.0f;// 旋轉角度
private float cameramove=0.5f;
private float[] bompos;
private boolean key[] = new boolean[9];
private int keystate;
private static final int FIRE = 0;
private static final int UP = 1;
private static final int DOWN = 2;
private static final int LEFT = 3;
private static final int RIGHT = 4;
private static final int GAME_A=5;
private static final int GAME_B=6;
private static final int GAME_C=7;
private static final int GAME_D=8;
static final int TERRAIN_ID = 14;
static final int CAMERA_ID = 15;
static final int SLEEP=30;
static final int AimNum=5;
private int round=0;
private int firnum=0;
private int score=0;
public AirFighterCanvas(AirFighterMIDlet parent, MainMenu menu)
{
// TODO Auto-generated constructor stub
super(true);
this.parent = parent;
this.menu = menu;
setFullScreenMode(true);
this.width = getWidth();
this.height = getHeight();
scroller = new StarHScroller(width, height);
init();
}
public void init()
{
world=new World();
light = new Light[2];
//System.out.println("World ID:"+world.getUserID());
background = new Background();
image2d=new Image2D(Image2D.RGB, scroller.getImage());
background.setImage(image2d);
world.setBackground(background);
try
{
crossImage = Image.createImage("/res/cross.png");
}
catch(Exception e)
{
}
light[0] = new Light();
light[0].setMode(Light.OMNI); // Light Mode
light[0].setColor(0xFFFFFF); // The color of the light
light[0].setTranslation(15.0f, 15.0f, -15.0f);
light[0].setUserID(2);
light[1] = new Light();
light[1].setMode(Light.OMNI); // Light Mode
light[1].setColor(0xFFFFFF); // The color of the light
light[1].setTranslation(-15.0f, 15.0f, 15.0f);
light[1].setUserID(3);
for (int i = 0; i < light.length; i++)
{
world.addChild(light[i]);
//System.out.println("Light ID:"+light[i].getUserID());
}
transform = new Transform();
transform.setIdentity();
this.g = this.getGraphics();
g3 = Graphics3D.getInstance();
gettrans=new float[16];
heightmap=MeshFactory.createHeightMap("/res/heightmap.m3g");
heightmap.setUserID(1);
world.addChild(heightmap);
//System.out.println("HeightMap ID:"+heightmap.getUserID());
loadcamera();
//loadcameraog();
bs=new BulletSystem(AimNum+1,world);
as = new AimSystem(AimNum, world,bs);
fe = new FountainEffect(-90);
ps = new ParticleSystem(fe, 10);
}
private void loadcamera()
{
camera = new Camera();
float aspect = (float) width / (float) height;
camera.setPerspective(60.0f, aspect, 0.1f, 100.0f);
camera.setTranslation(camerapos[0], camerapos[1], camerapos[2]);
world.addChild(camera);
world.setActiveCamera(camera);
}
private void loadcameraog()
{
try
{
// Find a specific Camera node in the World.
camera = (Camera) world.find(CAMERA_ID);
world.setActiveCamera(camera);
camera.getTransform(transform);
transform.get(gettrans);
camerapos[0]=gettrans[3];
camerapos[1]=gettrans[7];
camerapos[2]=gettrans[11];
//System.out.println("/ncameraog init:");
//System.out.println("Camera posog:"+camerapos[0]+" "+camerapos[1]+" "+camerapos[2]);
//System.out.println("Camera tran:"+gettrans[3]+" "+gettrans[7]+" "+gettrans[11]);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void cameramove()
{
//transform.postTranslate(0.0f, 0.0f,cameramove);
if (key[LEFT])
{
transform.postRotate(radian, 0.0f, 1.0f, 0.0f);
// System.out.println(".......left...............");
}
else if (key[RIGHT])
{
transform.postRotate(-radian, 0.0f,1.0f, 0.0f);
// System.out.println(".......right...............");
}
if (key[UP])
{
//camera.postRotate(radian, 1.0f, 0.0f, 0.0f);
transform.postRotate(radian, 1.0f, 0.0f, 0.0f);
// System.out.println(".......up...............");
}
else if (key[DOWN])
{
//camera.postRotate(-radian, 1.0f, 0.0f, 0.0f);
transform.postRotate(-radian, 1.0f, 0.0f, 0.0f);
}
if(key[GAME_A])
{
transform.postTranslate(0.0f,cameramove, 0.0f);
//System.out.println("key[GAME_A] processing.");
}
if(key[GAME_B])
{
transform.postTranslate(0.0f,-cameramove,0.0f);
}
if(key[GAME_C])
{
transform.postTranslate(0.0f, 0.0f,-cameramove);
}
if(key[GAME_D])
{
transform.postTranslate(0.0f, 0.0f,cameramove);
}
if (key[FIRE])
{
if(!bs.getBulletState(0))
{
transform.get(gettrans);
//System.out.println("/nFire Pressed:");
//System.out.println("Camera posog:"+camerapos[0]+" "+camerapos[1]+" "+camerapos[2]);
//System.out.println("Camera tran:"+gettrans[3]+" "+gettrans[7]+" "+gettrans[11]);
bs.start(0,camerapos,transform);
firnum++;//射擊數
}
}
//transform.get(gettrans);
//System.out.println("Camera pos:"+(camerapos[0]+gettrans[3])+" "+(camerapos[1]+gettrans[7])+" "+(camerapos[2]+gettrans[11]));
camera.setTransform(transform);
}
public void start()
{
gamePaused=false;
Thread t=new Thread(this);
t.start();
}
public void run()
{
while (!parent.isFinished())
{
if (!parent.isPaused())
{
draw3D(g);
//drawMenu(g);
flushGraphics();
try
{
Thread.sleep(SLEEP);//original 10
}
catch (InterruptedException e)
{
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void draw3D(Graphics g)
{
try {
keyprocess();
cameramove();
as.update(world);
int id= bs.update(world);
as.kpbulletsurvive(bs);
if(id!=0)
{
//bompos=as.hit(id);
bompos=bs.hit(id);
if(bompos!=null)
{
ps.init(bompos);
//System.out.println("trance");
}
}
// 綁定目标
g3.bindTarget(g); // Binds the given Graphics or mutable Image2D
//if(((++round)%10)==0)
// background.setImage(new Image2D(Image2D.RGB, scroller.getImage()));
//image2d.set(0, 0, width, height, scroller.getByteArray(scroller.getImage()));
// 渲染世界 // as the rendering target of this Graphics3D
g3.render(world); // Render the world
ps.emit(g3);
}
catch (Exception e)
{
System.out.println(".......render exception...............");
e.printStackTrace();
}
finally
{
g3.releaseTarget(); // 釋放目标
}
menupaint(g);
}
void menupaint(Graphics g)
{
//g.setColor(0, 255, 0);
//g.drawRect(width / 2 - 1, height / 2 - 1, 2, 2);
if(firnum<10)
{
score=0;
}else
{
score=(int)((as.gethitNum()+bs.gethitNum())/(firnum/10.0f)*10);
}
g.setColor(255, 255, 255);
g.drawString("Shoot:" + firnum, 0, 0, Graphics.TOP | Graphics.LEFT);
g.drawString("Hit:" + (as.gethitNum()+bs.gethitNum()), 0, 20, Graphics.TOP | Graphics.LEFT);
g.drawString("Score:"+score, width - 50, 0, Graphics.TOP| Graphics.LEFT);
transform.get(gettrans);
//System.out.println("/nFire Pressed:");
//System.out.println("Camera posog:"+camerapos[0]+" "+camerapos[1]+" "+camerapos[2]);
//System.out.println("Camera tran:"+gettrans[3]+" "+gettrans[7]+" "+gettrans[11]);
g.drawString("Pos[x]:"+(camerapos[0]+gettrans[3]), 0, height-60, 0);
g.drawString("Pos[y]:"+(camerapos[1]+gettrans[7]), 0, height-40, 0);
g.drawString("Pos[z]:"+(camerapos[2]+gettrans[11]), 0, height-20, 0);
g.drawString("Enemy:" + AimNum, width - 50, height - 20, Graphics.TOP | Graphics.LEFT);
g.drawImage(crossImage,getWidth()/2, getHeight()/2, Graphics.VCENTER | Graphics.HCENTER);
}
private void keyprocess()
{
keystate = getKeyStates();
if ((keystate & GameCanvas.FIRE_PRESSED) != 0)
key[FIRE] = true;
else
key[FIRE] = false;
if ((keystate & GameCanvas.UP_PRESSED) != 0)
key[UP] = true;
else
key[UP] = false;
if ((keystate & GameCanvas.DOWN_PRESSED) != 0)
key[DOWN] = true;
else
key[DOWN] = false;
if ((keystate & GameCanvas.LEFT_PRESSED) != 0)
key[LEFT] = true;
else
key[LEFT] = false;
if ((keystate & GameCanvas.RIGHT_PRESSED) != 0)
key[RIGHT] = true;
else
key[RIGHT] = false;
if ((keystate & GameCanvas.GAME_A_PRESSED)!= 0) //GameCanvas.KEY_NUM5
{
key[GAME_A]=true;
//System.out.println("key[GAME_A] pressed.");
}
else
key[GAME_A]=false;
if ((keystate & GameCanvas.GAME_B_PRESSED)!= 0) //GameCanvas.KEY_NUM5
{
key[GAME_B]=true;
//System.out.println("key[GAME_A] pressed.");
}
else
key[GAME_B]=false;
if ((keystate & GameCanvas.GAME_C_PRESSED)!= 0) //GameCanvas.KEY_NUM5
{
key[GAME_C]=true;
//System.out.println("key[GAME_A] pressed.");
}
else
key[GAME_C]=false;
if ((keystate & GameCanvas.GAME_D_PRESSED)!= 0) //GameCanvas.KEY_NUM5
{
key[GAME_D]=true;
//System.out.println("key[GAME_A] pressed.");
}
else
key[GAME_D]=false;
}
public void stop()
{
gamePaused=true;
}
public boolean isPaused()
{
return gamePaused;
}
public void gameContinue()
{
gamePaused = false;
}
}
AirFighterMIDlet.java
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class AirFighterMIDlet extends MIDlet
{
private Display display = null;
private SplashCanvas splash;
boolean started = false;
boolean finished = false;
boolean paused=false;
Thread drawThread;
AirFighterCanvas canvas;
public AirFighterMIDlet()
{
// TODO Auto-generated constructor stub
splash = new SplashCanvas(this);
this.display = Display.getDisplay(this);
}
protected void startApp()
{
// TODO Auto-generated method stub
if (display == null)
{
display = Display.getDisplay(this);
}
//splash screen to the display
setDisplayable(splash);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{
// TODO Auto-generated method stub
setFinished();
}
protected void pauseApp()
{
// TODO Auto-generated method stub
paused=true;
}
public void setDisplayable(Displayable dl)
{
display.setCurrent(dl);
}
public synchronized boolean isFinished()
{
return finished;
}
public synchronized void setFinished()
{
finished = true;
}
public synchronized boolean isPaused()
{
return paused;
}
}
BaseRMS.java
import javax.microedition.rms.*;
import java.util.*;
import java.io.*;
abstract public class BaseRMS {
private String rmsName;
private RecordStore recordStore;
BaseRMS(String rmsName) {
this.rmsName = rmsName;
}
public void open() throws Exception
{
try
{
recordStore = RecordStore.openRecordStore(this.rmsName,true);
if (recordStore.getNumRecords() > 0)
{
loadData();
}
else
{
createDefaultData();
}
}
catch (Exception e)
{
throw new Exception(this.rmsName+"::open::"+e);
}
}
public void close()
{
if (recordStore != null)
{
try
{
recordStore.closeRecordStore();
}
catch(Exception e)
{
System.out.println(this.rmsName+"::close::"+e);
}
}
}
public RecordStore getRecordStore()
{
return this.recordStore;
}
public String getRMSName()
{
return this.rmsName;
}
abstract void loadData() throws Exception;
abstract void createDefaultData() throws Exception;
abstract void updateData() throws Exception;
}
Bullet.java
import java.util.Random;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Loader;
import javax.microedition.m3g.Mesh;
import javax.microedition.m3g.RayIntersection;
import javax.microedition.m3g.Transform;
public class Bullet
{
private Mesh mesh;
private float scaleobj = 0.2f;
private float scalebullet = 0.1f;
RayIntersection ri;
private Random rand;
private boolean life=true;
private Transform transform;
private int itemID=0;
private float[] pos = { 0.0f, 0.0f, 0.0f };
private float[] posinit = { 0.0f, 0.0f, 0.0f };
private float[] poshide={0.0f,-3.0f,0.0f};
private float[] gettrans;
private float vog = 2.0f;
private float vobject=0.05f;
private float v = 0.0f;
private float dis=0.2f;
public Bullet(int ID,Group group,Random ran)
{
mesh = MeshFactory.createSquare("/res/Legion.png");
group.addChild(mesh);
mesh.translate(poshide[0], poshide[1], poshide[2]);
mesh.setUserID(ID);
setID(ID);
gettrans=new float[16];
transform=new Transform();
transform.setIdentity();
ri = new RayIntersection();
rand=ran;
setLife(false);
}
public void init(float[] posog,Transform tran,boolean flag)
{
System.arraycopy(posog, 0,posinit, 0, posog.length);
transform.set(tran);
transform.get(gettrans);
pos[0]=posinit[0]+gettrans[3];
pos[1]=posinit[1]+gettrans[7];
pos[2]=posinit[2]+gettrans[11];
if(flag)
{
//true for Camera
v=vog;
mesh.setScale(scalebullet, scalebullet, scalebullet);
}
else
{
v=vobject+rand.nextFloat()*0.05f;
mesh.setScale(scaleobj, scaleobj, scaleobj);
}
//System.out.println("/nBullet init:");
//System.out.println("Camera posog:"+posog[0]+" "+posog[1]+" "+posog[2]);
//System.out.println("Bullet posog:"+pos[0]+" "+pos[1]+" "+pos[2]);
//System.out.println("Camera tran:"+gettrans[3]+" "+gettrans[7]+" "+gettrans[11]);
setLife(true);
mesh.setTranslation(pos[0], pos[1],pos[2]);
}
public int update(Group group)
{
int id=0;
mesh.postRotate(15.0f, 0.0f, 0.0f, 1.0f);
if (group.pick(-1, pos[0], pos[1], pos[2], 1.0f, 0.0f, 0.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if(group.pick(-1, pos[0], pos[1], pos[2], -1.0f, 0.0f, 0.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if(group.pick(-1, pos[0], pos[1], pos[2], 0.0f, 1.0f, 0.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if (group.pick(-1, pos[0], pos[1], pos[2], 0.0f,-1.0f, 0.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if(group.pick(-1, pos[0], pos[1], pos[2], 0.0f, 0.0f, 1.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if(group.pick(-1, pos[0], pos[1], pos[2], 0.0f, 0.0f, -1.0f, ri)&& (ri.getDistance() < dis))
{
id = ri.getIntersected().getUserID();
//System.out.println("Bullet Intersected:"+id);
//System.out.println("Bullet Intersected Class:"+ri.getIntersected().getClass());
//System.out.println("Bullet Intersected Parent:"+ri.getIntersected().getParent());
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else if(pos[0]<=-15.0f||pos[0]>=15.0f||pos[2]<=-15.0f||pos[2]>=15.0f||pos[1]<=-0.0f||pos[1]>=10.0f)
{
setLife(false);
System.arraycopy(poshide, 0,pos, 0, poshide.length);
}
else
{
transform.postTranslate(0.0f, 0.0f, -v);
transform.get(gettrans);
pos[0]=posinit[0]+gettrans[3];
pos[1]=posinit[1]+gettrans[7];
pos[2]=posinit[2]+gettrans[11];
}
mesh.setTranslation(pos[0], pos[1], pos[2]);
//System.out.println("Bullet pos:"+pos[0]+","+pos[1]+","+pos[2]);
return id;
}
void setLife(boolean life)
{
this.life = life;
}
boolean getLife()
{
return life;
}
void setID(int id)
{
itemID = id;
}
int getID()
{
return itemID;
}
float[] getPos()
{
return pos;
}
}
BulletSystem.java
import java.util.Random;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Transform;
public class BulletSystem
{
Bullet[] bullet=null;
int hitnum=0;
int bulletnum=0;
private Random rand;
public BulletSystem(int bulletNum,Group group)
{
bullet=new Bullet[bulletNum];
bulletnum=bulletNum;
rand=new Random();
for(int i=0;i<bullet.length;i++)
{
bullet[i]=new Bullet(100+i,group,rand);
//System.out.println("Bullet"+i+"ID:"+bullet[i].getID());
}
}
public int getBulletnum()
{
return bulletnum;
}
public boolean getBulletState(int i)
{
return bullet[i].getLife();
}
public void start(int i,float[] posog,Transform tran)
{
bullet[i].init(posog, tran,i==0?true:false);
}
public int update(Group group)
{
int id=0;
int temp=0;
for(int i=0;i<bullet.length;i++)
{
if(bullet[i].getLife())
{
temp=bullet[i].update(group);
if(temp!=0)
id=temp;
}
}
return id;
}
public float[] hit(int itemID)
{
float pos[]=null;
for(int i=1;i<bullet.length;i++)
{
if(bullet[i].getID()==itemID)
{
hitnum++;
pos=bullet[i].getPos();
bullet[i].setLife(false);
}
}
return pos;
}
int gethitNum()
{
return hitnum;
}
}
FountainEffect.java
import java.util.Random;
import javax.microedition.m3g.Graphics3D;
import javax.microedition.m3g.Mesh;
import javax.microedition.m3g.Transform;
public class FountainEffect
{
// The angle of particle emission
private int angle = 90;
// The sine and cosine of the current angle
private float[] trig = {1.0f, 0.0f};
// The emitting origin
private float[] initpos = {0.0f, 7.0f, -7.0f};
private float[] initvel = {0.0f, 0.0f, 0.0f};
// The randomizer
Random rand = null;
// The mesh
Mesh mesh = null;
// The transformation matrix
Transform trans = new Transform();
// The scale
//縮放刻度
float scale = 1.0f;
public FountainEffect(int angle)
{
// Init the bitmap
scale=0.15f;
mesh = MeshFactory.createAlphaPlane("/res/particle.png",0xffffff);
// Set the angle
setAngle(angle);
// Get randomizer
rand = new Random();
}
public void update(Particle p)
{
float[] ppos = p.getPos();
float[] vel = p.getVel();
ppos[0] += vel[0];
ppos[1] += vel[1];
ppos[2] += vel[2];
p.setPos(ppos);
p.setLife(p.getLife() - p.getDegradation());
if(p.getLife() < -0.001f)
{
// init(p,new float[]{0.0f,3.0f,-5.0f});
p.setPos(initpos);
p.setVel(initvel);
}
}
public void render(Particle p, Graphics3D g3d)
{
if(p.getLife()>0.01f)
{
// Calculate the alpha
int alpha = (int)(255 * p.getLife());
// Create the color
int color = p.getColor() | (alpha << 24);//alpha左移3位元組
// Set alpha
MeshOperator.setMeshAlpha(mesh, color);
// Transform
trans.setIdentity();
//使圖檔始終面對錄影機
float[] pos = p.getPos();
trans.postTranslate(pos[0], pos[1], pos[2]);
trans.postRotate(rand.nextFloat()*90, 1.0f, 0.0f, 0.0f);
trans.postRotate(rand.nextFloat()*90, 0.0f, 0.0f, 1.0f);
trans.postScale(scale, scale, scale);
// System.out.print("mesh pos="+pos[0]+","+pos[1]+","+pos[2]);
// System.out.println(" life="+p.getLife()+" col="+alpha);
// Render
g3d.render(mesh, trans);
}
else
{
}
}
public void init(Particle p, float[] pos)
{
// Set the particle's life
p.setLife(1.0f);
p.setPos(pos);
// Create the particle's velocties
float[] vel = new float[3];
//數度從0.1~0.2
float xyvel = rand.nextFloat() * 0.05f+0.05f;
// We want the particle to die slowly
p.setDegradation(xyvel / 3f);
// Set velocities according to trigonometry with a small deviation
// ...=1.0f*cos/sin +
vel[0] = xyvel * trig[1] + rand.nextFloat() * 0.125f-0.0625f;
vel[1] = xyvel * trig[0] + rand.nextFloat() * 0.025f-0.025f;
// No movement in depth
vel[2] = 0.0f;
// Set the velocity
p.setVel(vel);
// Set the random color
int r = (int)(120 * rand.nextFloat()) + 135;
int g = (int)(120 * rand.nextFloat()) + 135;
int b = (int)(120 * rand.nextFloat()) + 135;
int col = (r << 16) | (g << 8) | b;
p.setColor(col);
}
public void setAngle(int angle)
{
this.angle = angle;
trig[0] = (float)Math.sin(Math.toRadians(angle));
trig[1] = (float)Math.cos(Math.toRadians(angle));
}
public int getAngle() {
return angle;
}
}
HighScore.java
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.List;
public class HighScore extends List implements CommandListener
{
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
private Command back=new Command("back",Command.BACK,2);
private HighScoreRMS db;
public HighScore(AirFighterMIDlet parent, MainMenu menu)
{
super("HighScore",List.IMPLICIT);
this.parent = parent;
this.menu = menu;
db=new HighScoreRMS("HighScore");
db.loadHighScore();
String[] temp=new String[9];
temp=db.getHighScore();
this.append("Level Seconds Score",null);
this.addCommand(back);
this.setCommandListener(this);
for(int i=0;i<3;i++)
{
//temp=db.gethighscore(i);
if(i%3==0)
this.append(" ",null);
this.append(temp[i*3]+" "+temp[i*3+1]+" "+temp[i*3+2],null);
}
}
protected void paint(Graphics g)
{
//Paint the high scores here
}
public void commandAction(Command p0, Displayable p1)
{
if (p0 == back)
{
parent.setDisplayable(menu);
}
}
}
HighScoreRMS.java
import javax.microedition.rms.*;
import java.util.*;
import java.io.*;
public class HighScoreRMS extends BaseRMS
{
private int sound = 0; //0:on;1:off;
private int shake = 0; //0:on;1:off;
private String[] HighScorelist=null;
public HighScoreRMS(String rmsName)
{
super(rmsName);
HighScorelist=new String[9];
}
public void loadHighScore()
{
try
{
// Will call either loadData() or createDefaultData()
this.open();
// Add any other neccessary processing, in this case there is none
// Close
if (this.getRecordStore() != null)
this.close();
}
catch (Exception e)
{
System.out.println("Error loading HighScoreRMS" + e);
}
}
public String[] getHighScore()
{
return this.HighScorelist;
}
public void updateHighScore(String[] str)
{
try
{
// load current scores
this.open();
// update data
this.HighScorelist = str;
// Update High Scores
updateData();
// close
if (this.getRecordStore() != null)
this.close();
}
catch (Exception e)
{
System.out.println(this.getRMSName() + "::updateHighScore::" + e);
}
}
protected void loadData() throws Exception
{
try
{
byte[] record = this.getRecordStore().getRecord(1);
DataInputStream istream = new DataInputStream(new ByteArrayInputStream(record,0,record.length));
for(int i=0;i<9;i++)
{
HighScorelist[i]=istream.readUTF();
}
}
catch (Exception e)
{
throw new Exception (this.getRMSName() + "::loadData::" + e);
}
}
protected void createDefaultData() throws Exception
{
try
{
ByteArrayOutputStream bstream = new ByteArrayOutputStream(30);
DataOutputStream ostream = new DataOutputStream(bstream);
ostream.writeUTF("1");
ostream.writeUTF("60");
ostream.writeUTF("300");
ostream.writeUTF("2");
ostream.writeUTF("60");
ostream.writeUTF("200");
ostream.writeUTF("3");
ostream.writeUTF("60");
ostream.writeUTF("100");
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().addRecord(record, 0, record.length);
}
catch (Exception e)
{
throw new Exception(this.getRMSName() + "::createDefaultData::" + e);
}
}
protected void updateData() throws Exception
{
try
{
ByteArrayOutputStream bstream = new ByteArrayOutputStream(30);
DataOutputStream ostream = new DataOutputStream(bstream);
for(int i=0;i<9;i++)
{
ostream.writeUTF(HighScorelist[i]);
}
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().setRecord(1, record, 0, record.length);
}
catch(Exception e)
{
throw new Exception(this.getRMSName() + "::updateData::" + e);
}
}
}
Instructions.java
//Text instructions. Text can be written in constructor or in own method.
//Developer should remember that also instruction texts should be
//internationalized
import javax.microedition.lcdui.*;
public class Instructions extends Form implements CommandListener
{
//Command for going next instruction if needed
private Command more = new Command(Resources.getString(Resources.ID_GAME_MORE),Command.OK, 1);
//Command for going back to the main menu
private Command back = new Command("Back", Command.BACK, 2);
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
public Instructions(String title,AirFighterMIDlet parent, MainMenu menu)
{
super(title);
this.parent = parent;
this.menu = menu;
this.addCommand(back);
this.addCommand(more);
this.setCommandListener(this);
this.append("Up:向上旋轉瞄準器;/n" +
"Down:向下旋轉瞄準器;/n"+
"Left:向左旋轉瞄準器;/n"+
"Right:向右旋轉瞄準器;/n"+
"1(Game_A):向前移動瞄準器;/n"+
"3(Game_B):向後移動瞄準器;/n"+
"5(Game_C):向瞄準器;/n"+
"7(Game_D):向瞄準器./n");
}
public void commandAction(Command p0, Displayable p1)
{
if (p0 == more)
{
//go to the next if needed e.g animation
//parent.setDisplayable(new InstructionAnimation(parent));
}
else if (p0 == back)
{
parent.setDisplayable(menu);
}
}
}
Language.java
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
public class Language extends List implements CommandListener
{
private AirFighterMIDlet parent = null;
private OptionList opt= null;
private LanguageRMS db;
private Command back = new Command("Back", Command.BACK, 2);
private String lang;
public Language(AirFighterMIDlet parent,OptionList optf)
{
// TODO Auto-generated constructor stub
super(Resources.getString(Resources.ID_GAME_LANGUAGE),List.IMPLICIT);
this.opt = optf;
this.parent=parent;
lang=new String();
db=new LanguageRMS("Language");
db.loadLanguage();
lang=db.getlanguage();
this.addCommand(back);
this.setCommandListener(this);
this.append(Resources.supportedLocales[0],null);
this.append(Resources.supportedLocales[1],null);
this.append(Resources.supportedLocales[2],null);
this.append(Resources.supportedLocales[3],null);
}
public Language(String arg0, int arg1, String[] arg2, Image[] arg3)
{
super(arg0, arg1, arg2, arg3);
// TODO Auto-generated constructor stub
}
public void commandAction(Command p0, Displayable p1)
{
if (p0==back)
{
//System.out.println("Back pressed:");
//System.out.println(lang);
db.updateLanguage(lang);
//System.out.println("After update:"+db.getlanguage());
parent.setDisplayable(opt);
}
else
{
List lis = (List) p1;
int idx = lis.getSelectedIndex();
switch (idx)
{
case 0:
//TODO
lang=Resources.supportedLocales[0];
break;
case 1:
//TODO
lang=Resources.supportedLocales[1];
break;
case 2:
//TODO
lang=Resources.supportedLocales[2];
break;
case 3:
lang=Resources.supportedLocales[3];
break;
//More if needed
default:
break;
}
//System.out.println("lang:"+lang);
}
}
}
LanguageRMS.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class LanguageRMS extends BaseRMS
{
private String lang;
public LanguageRMS(String rmsName)
{
// TODO Auto-generated constructor stub
super(rmsName);
lang=new String();
}
public void loadLanguage()
{
try
{
// Will call either loadData() or createDefaultData()
this.open();
// Add any other neccessary processing, in this case there is none
// Close
if (this.getRecordStore() != null)
this.close();
}
catch (Exception e)
{
System.out.println("Error loading Settings" + e);
}
}
public String getlanguage()
{
return this.lang;
}
public void updateLanguage(String lan)
{
try
{
// load current scores
this.open();
// update data
this.lang =lan;
// Update High Scores
updateData();
// close
if (this.getRecordStore() != null)
this.close();
}
catch (Exception e)
{
System.out.println(this.getRMSName() + "::updateSettings::" + e);
}
}
protected void createDefaultData() throws Exception
{
// TODO Auto-generated method stub
try
{
ByteArrayOutputStream bstream = new ByteArrayOutputStream(20);
DataOutputStream ostream = new DataOutputStream(bstream);
ostream.writeUTF("en");
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().addRecord(record, 0, record.length);
}
catch (Exception e)
{
throw new Exception(this.getRMSName() + "::createDefaultData::" + e);
}
}
void loadData() throws Exception
{
// TODO Auto-generated method stub
try
{
byte[] record = this.getRecordStore().getRecord(1);
DataInputStream istream = new DataInputStream(new ByteArrayInputStream(record,0,record.length));
lang= istream.readUTF();
}
catch (Exception e)
{
throw new Exception (this.getRMSName() + "::loadData::" + e);
}
}
void updateData() throws Exception
{
// TODO Auto-generated method stub
try
{
ByteArrayOutputStream bstream = new ByteArrayOutputStream(20);
DataOutputStream ostream = new DataOutputStream(bstream);
ostream.writeUTF(lang);
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().setRecord(1, record, 0, record.length);
}
catch(Exception e)
{
throw new Exception(this.getRMSName() + "::updateData::" + e);
}
}
}
MainMenu.java
import javax.microedition.lcdui.*;
public class MainMenu extends List implements CommandListener
{
private AirFighterMIDlet parent=null;
private AirFighterCanvas game=null;
private LanguageRMS dbl;
private String lang;
private final Command exitCommand = new Command("Exit", Command.EXIT, 1);
public MainMenu(String p0, int p1, String[] p2, Image[] p3,AirFighterMIDlet parent)
{
super(p0, p1, p2, p3);
init(parent);
}
public MainMenu(String p0, int p1, AirFighterMIDlet parent)
{
super(p0, p1);
init(parent);
}
public void Refreshlang()
{
dbl=new LanguageRMS("Language");
dbl.loadLanguage();
lang=dbl.getlanguage();
this.deleteAll();
this.append(Resources.getString(lang,Resources.ID_GAME_NEW), null);
this.append(Resources.getString(lang,Resources.ID_GAME_OPTIONS),null);
this.append(Resources.getString(lang,Resources.ID_GAME_HIGHSCORES), null);
this.append(Resources.getString(lang,Resources.ID_GAME_INSTRUCTIONS), null);
this.append(Resources.getString(lang,Resources.ID_GAME_ABOUT),null);
this.append(Resources.getString(lang,Resources.ID_GAME_EXIT),null);
}
public void init(AirFighterMIDlet parent)
{
this.parent = parent;
dbl=new LanguageRMS("Language");
dbl.loadLanguage();
lang=dbl.getlanguage();
this.setCommandListener(this);
//if game paused then "Continue" should be available in
//selection list
//These must be with or without icons
if (game != null && game.isPaused())
{
if(!(this.getString(0).equals(new String(Resources.getString(lang,Resources.ID_GAME_CONTINUE)))))
{
this.insert(0,Resources.getString(lang,Resources.ID_GAME_CONTINUE),null);
}
this.setSelectedIndex(0,true);
}
else
{
//These must be with or without icons
this.append(Resources.getString(lang,Resources.ID_GAME_NEW), null);
this.append(Resources.getString(lang,Resources.ID_GAME_OPTIONS),null);
this.append(Resources.getString(lang,Resources.ID_GAME_HIGHSCORES), null);
this.append(Resources.getString(lang,Resources.ID_GAME_INSTRUCTIONS), null);
this.append(Resources.getString(lang,Resources.ID_GAME_ABOUT),null);
this.append(Resources.getString(lang,Resources.ID_GAME_EXIT),null);
}
}
public void commandAction(Command p0, Displayable p1)
{
if(p0 == exitCommand)
{
System.out.println("ExitCommand Pressed.");
parent.setFinished();
parent.setDisplayable(this);
}
else
{
List lis = (List)p1;
String selected =lis.getString(lis.getSelectedIndex());
System.out.println(selected);
if (selected.equals(Resources.getString(lang,Resources.ID_GAME_NEW)))
{
game = new AirFighterCanvas(parent, this);
game.addCommand(exitCommand);
game.setCommandListener(this);
parent.setDisplayable(game);
game.start();
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_OPTIONS)))
{
parent.setDisplayable(new OptionList(Resources.getString(lang,Resources.ID_GAME_OPTIONS),List.IMPLICIT,parent, this));
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_HIGHSCORES)))
{
parent.setDisplayable(new HighScore(parent,this));
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_INSTRUCTIONS)))
{
parent.setDisplayable(new Instructions(Resources.getString(lang,Resources.ID_GAME_INSTRUCTIONS),parent,this));
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_ABOUT)))
{
parent.setDisplayable(new About(Resources.getString(lang,Resources.ID_GAME_ABOUT),parent,this));
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_EXIT)))
{
parent.notifyDestroyed();
}
else if (selected.equals(Resources.getString(lang,Resources.ID_GAME_CONTINUE)))
{
if (game != null)
{
game.gameContinue();
parent.setDisplayable(game);
}
else
{}
}
}
}
}
MeshFactory.java
import javax.microedition.lcdui.Image;
import javax.microedition.m3g.Appearance;
import javax.microedition.m3g.Background;
import javax.microedition.m3g.Group;
import javax.microedition.m3g.Image2D;
import javax.microedition.m3g.Loader;
import javax.microedition.m3g.Material;
import javax.microedition.m3g.Mesh;
import javax.microedition.m3g.PolygonMode;
import javax.microedition.m3g.Texture2D;
import javax.microedition.m3g.TriangleStripArray;
import javax.microedition.m3g.VertexArray;
import javax.microedition.m3g.VertexBuffer;
public class MeshFactory {
private static VertexArray vertexarray; // 頂點數組
private static VertexBuffer vertexbuff; // 緩沖器
private static VertexArray texturearray; // 紋理數組
private static VertexArray normalarray;
private static Material material;
private static TriangleStripArray TSArray; // 三角形帶
private static Appearance appearnce; // 外觀
private static Texture2D t2d;
// 底頂點
private static final byte[] s_plane_v = new byte[]
{ -1, 0, 1, 1, 0, 1,
1, 0, -1, -1, 0, -1 };
private static final int[] s_plane_index = { 0, 1, 3, 2 };
private static final int[] plane_indices = new int[] { 4 };
private static final byte[] s_plane_normal = new byte[] {
0, 1, 0, 0, 1, 0,
0, 1, 0, 0, 1, 0 };
// 紋理坐标
private static final byte[] s_plane_texture = new byte[]{
0, 1, 1, 1, 1,0, 0, 0 };
// 8 頂點
private static final byte[] s_vertices =
{
// 0 1 2 3
-1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
// 4,6,5,7,
-1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,
// 2 3 6 7
-1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1,
// 0,4,1,5,
-1, -1, 1, -1,-1, -1, 1,-1, 1, 1,-1, -1,
// 1 5 3 7
1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1,
// 0,2,4,6
-1,-1, 1, -1, 1, 1, -1,-1,-1, -1, 1, -1,
};
// 定義各個面,外觀全部逆時針
private static final int[] s_indices = { 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23
};
// 面頂點長度
private static final int[] indices_Length = new int[] { 4, 4, 4, 4, 4, 4 };
// 紋理坐标
private static final byte[] s_texture = new byte[] { 0, 1, 1, 1, 0, 0, 1,
0,
1, 1, 1, 0, 0, 1, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1,
0, 0, 0, 1, 1, 0, 1, 1,
0, 1, 1, 1, 0, 0, 1, 0,
1, 1, 1, 0, 0, 1, 0, 0
};
// 正方體法線向量
private static final byte[] s_normal = new byte[] {
// 0 1 2 3
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
// 4,6,5,7,
0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
// 2 3 6 7
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
// 0,4,1,5,
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
// 1 5 3 7
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
// 0,2,4,6
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
};
public static Group createHeightMap(String path)
{
Group group=null;
try
{
group=(Group)Loader.load(path)[0];
group.postRotate(-90.0f, 1.0f, 0.0f, 0.0f);
}
catch (Exception e)
{
e.printStackTrace();
}
return group;
}
public static Group createGoomba(String path)
{
Group goomba=null;
try
{
//System.out.println("Loading Aim Model:"+path);
goomba=(Group)Loader.load(path)[0];
goomba.postRotate(-90.0f, 1.0f, 0.0f, 0.0f);
}
catch (Exception e)
{
System.out.println("Model Loadiing ERROR");
e.printStackTrace();
}
return goomba;
}
public static Mesh createPlane(String path)
{
Mesh mesh=null;
// 頂點矩陣
vertexarray = new VertexArray(s_plane_v.length / 3, 3, 1);
vertexarray.set(0, s_plane_v.length / 3, s_plane_v);
normalarray = new VertexArray(s_plane_normal.length / 3, 3, 1);
normalarray.set(0, s_plane_normal.length / 3, s_plane_normal);
// 面三角形條帶
TSArray = new TriangleStripArray(s_plane_index, plane_indices);// 索引,索引長度
texturearray = new VertexArray(s_plane_texture.length / 2, 2, 1);
texturearray.set(0, s_plane_texture.length / 2, s_plane_texture);
vertexbuff = new VertexBuffer();
vertexbuff.setPositions(vertexarray, 1.0f, null);
vertexbuff.setTexCoords(0, texturearray, 1.0f, null);
vertexbuff.setNormals(normalarray);
//vertexbuff.setDefaultColor(0xffffffff);
// 設定多邊形模式設定
PolygonMode polygonMode = new PolygonMode();
// 起用透視修正,這樣在多個三角形組成的平面中,紋理就不會彎曲
polygonMode.setPerspectiveCorrectionEnable(true);
// 建立紋理
t2d = createTexture(path);
// 材料
material = new Material();
material.setVertexColorTrackingEnable(true);
// 生成外貌
appearnce = new Appearance();
appearnce.setPolygonMode(polygonMode);
appearnce.setMaterial(material);
appearnce.setTexture(0, t2d);
// 生成網眼
mesh = new Mesh(vertexbuff, TSArray, appearnce);
return mesh;
}
public static Mesh createSquare(String path)
{
Mesh mesh = null;
// Create vertex data.
// 頂點矩陣
vertexarray = new VertexArray(s_vertices.length / 3, 3, 1);
vertexarray.set(0, s_vertices.length / 3, s_vertices);
normalarray = new VertexArray(s_normal.length / 3, 3, 1);
normalarray.set(0, s_normal.length / 3, s_normal);
// 面三角形條帶
TSArray = new TriangleStripArray(s_indices, indices_Length);// 索引,索引長度
texturearray = new VertexArray(s_texture.length / 2, 2, 1);
texturearray.set(0, s_texture.length / 2, s_texture);
vertexbuff = new VertexBuffer();
vertexbuff.setPositions(vertexarray, 1.0f, null);
vertexbuff.setTexCoords(0, texturearray, 1.0f, null);
vertexbuff.setNormals(normalarray);
// 設定多邊形模式設定
PolygonMode polygonMode = new PolygonMode();
polygonMode.setCulling(PolygonMode.CULL_BACK);
polygonMode.setPerspectiveCorrectionEnable(true);
// 建立紋理
t2d = createTexture(path);
// 材料
material = new Material();
material.setVertexColorTrackingEnable(true);
// 生成外貌
appearnce = new Appearance();
appearnce.setPolygonMode(polygonMode);
appearnce.setMaterial(material);
appearnce.setTexture(0, t2d);
// appearnce.setFog(fog);
// 生成網眼
mesh = new Mesh(vertexbuff, TSArray, appearnce);
return mesh;
}
public static Mesh createAlphaPlane(String path,int alpha)
{
Mesh mesh=createPlane(path);
MeshOperator.convertToBlended(mesh, alpha, Texture2D.FUNC_BLEND);
return mesh;
}
private static Texture2D createTexture(String path)
{
Texture2D texture = null;
try {
// 載入圖檔
Image texImg = Image.createImage(path); // Load the image
// 建立紋理
//create the texture from the image
//注意Image2D.RGB /Image2D.RGBA的差別
texture = new Texture2D(new Image2D(Image2D.RGBA, texImg));
// 設定混合方式
texture.setBlending(Texture2D.FUNC_REPLACE);
//repeat the texture.
texture.setWrapping(Texture2D.WRAP_CLAMP,Texture2D.WRAP_CLAMP);
// 設定過濾方式
texture.setFiltering(Texture2D.FILTER_BASE_LEVEL, Texture2D.FILTER_NEAREST);
} catch (Exception e) {
System.out.println("Failed to create texture");
}
return texture;
}
private static Background createBackground(String path)
{
Background background=null;
return background;
}
}
MeshOperator.java
import javax.microedition.m3g.CompositingMode;
import javax.microedition.m3g.Mesh;
public class MeshOperator
{
public static void setMeshAlpha(Mesh m, int alpha)
{
m.getVertexBuffer().setDefaultColor(alpha);
}
public static void convertToBlended(Mesh m, int alpha, int textureBlending)
{
// Set the alpha
setMeshAlpha(m, alpha);
// Fix the compositing mode
CompositingMode cm = new CompositingMode();
cm.setBlending(CompositingMode.ALPHA);
m.getAppearance(0).setCompositingMode(cm);
m.getAppearance(0).getTexture(0).setBlending(textureBlending);
}
}
OptionList.java
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
public class OptionList extends List implements CommandListener
{
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
private Settings db;
private LanguageRMS dbl;
private String lang;
//private KeyDefinitions def = null;
private Command back = new Command("Back", Command.BACK, 2);
private String[] change;
private int[] sets;
public OptionList(String p0, int p1, String[] p2, Image[] p3,AirFighterMIDlet parent, MainMenu menu)
{
super(p0, p1, p2, p3);
this.menu = menu;
init(parent);
}
public OptionList(String p0, int p1, AirFighterMIDlet parent,MainMenu menu)
{
super(p0, p1);
this.menu = menu;
init(parent);
}
private void init(AirFighterMIDlet parent)
{
//System.out.println("Parent:"+this.parent.toString());
this.parent = parent;
dbl=new LanguageRMS("Language");
dbl.loadLanguage();
lang=dbl.getlanguage();
//System.out.println("Menu:"+menu.toString());
//System.out.println("Parent:"+this.parent.toString());
this.addCommand(back);
this.setCommandListener(this);
db=new Settings("Settings");
db.loadSettings();
change=new String[2];
sets=new int[2];
change[0]=change[1]="OFF";
sets[0]=db.getsound();
sets[1]=db.getshake();
//System.out.println(db.getRMSName());
//System.out.println("before:"+db.getsound()+" "+db.getshake());
if(sets[0]==0)
change[0]="ON";
if(sets[1]==0)
change[1]="ON";
//These are just a examples for the game specific options
this.append(Resources.getString(lang,Resources.ID_GAME_SOUNDS)+":/t"+change[0],null);
this.append(Resources.getString(lang,Resources.ID_GAME_VIBRA)+":/t"+change[1],null);
this.append(Resources.getString(lang,Resources.ID_GAME_LANGUAGE)+":/t",null);
}
private void setstring(String s0,String s1)
{
this.set(0, s0, null);
this.set(1, s1, null);
}
public void commandAction(Command p0, Displayable p1)
{
if (p0 == back)
{
db.updateSettings(sets[0],sets[1]);
//System.out.println("After:"+db.getsound()+" "+db.getshake());
parent.setDisplayable(menu);
menu.Refreshlang();
}
else
{
List lis = (List) p1;
int idx = lis.getSelectedIndex();
switch (idx)
{
case 0:
//TODO
if(change[0]=="ON")
{
sets[0]=1;
change[0]="OFF";
}
else
{
sets[0]=0;
change[0]="ON";
}
break;
case 1:
//TODO
if(change[1]=="ON")
{
change[1]="OFF";
sets[1]=1;
}
else
{
change[1]="ON";
sets[1]=0;
}
break;
case 2:
//TODO
parent.setDisplayable(new Language(parent,this));
break;
case 3:
//parent.setDisplayable(def);
break;
//More if needed
default:
break;
}
setstring(Resources.getString(lang,Resources.ID_GAME_SOUNDS)+":/t"+change[0],Resources.getString(lang,Resources.ID_GAME_VIBRA)+":/t"+change[1]);
}
}
}
Particle.java
public class Particle
{
// The life of the particle. Goes from 1.0f to 0.0f
// 粒子的壽命. 從 1.0f 到 0.0f
private float life = 0.001f;
// The degradation of the particle
//衰變
private float degradation = 0.01f;
// The velocities of the particle
//速率
private float[] vel = {0.0f, 0.0f, 0.0f};
// The position of the particle
//位置
private float[] pos = {1.0f, 1.0f, 3.0f};
// The color of the particle (RGB format 0xRRGGBB)
// 粒子的顔色 (RGB 形式 0xRRGGBB)
private int color = 0xffffff;
public Particle()
{
}
public Particle(float[] velocity, float[] position, int color)
{
if((velocity!=null)&&(velocity.length==3))
setVel(velocity);
if((position!=null)&&(velocity.length==3))
setPos(position);
if(color>=0)
this.setColor(color);
}
void setLife(float life) {
this.life = life;
}
float getLife() {
return life;
}
void setVel(float[] tvel) {
System.arraycopy(tvel, 0, vel, 0, vel.length);
}
float[] getVel() {
return vel;
}
void setPos(float[] tpos) {
System.arraycopy(tpos, 0, pos, 0, pos.length);
}
float[] getPos() {
return pos;
}
void setColor(int color) {
this.color = color;
}
int getColor() {
return color;
}
public void setDegradation(float degradation) {
this.degradation = degradation;
}
public float getDegradation() {
return degradation;
}
}
ParticleSystem.java
import javax.microedition.m3g.Graphics3D;
public class ParticleSystem
{
//效果,接口
private FountainEffect ft = null;
// The particles
//粒子
Particle[] parts = null;
public ParticleSystem(FountainEffect effect, int numParticles)
{
// Copy the effect
this.ft = effect;
// Init the particles
parts = new Particle[numParticles];
for(int i = 0; i < parts.length; i++)
{
parts[i] = new Particle();
}
}
public void init(float pos[])
{
for(int i = 0; i < parts.length; i++)
{
ft.init(parts[i],pos);
}
// System.out.println("parts init");
}
public void emit(Graphics3D g3d)
{
for(int i = 0; i < parts.length; i++)
{
ft.update(parts[i]);
ft.render(parts[i], g3d);
}
}
}
Resources.java
public class Resources
{
// Identifiers for text strings.
public static final int ID_GAME_NEW = 0;
public static final int ID_GAME_OPTIONS = 1;
public static final int ID_GAME_HIGHSCORES = 2;
public static final int ID_GAME_INSTRUCTIONS = 3;
public static final int ID_GAME_ABOUT = 4;
public static final int ID_GAME_CONTINUE = 5;
public static final int ID_GAME_BACK = 6;
public static final int ID_GAME_MORE = 7;
public static final int ID_GAME_EXIT = 8;
public static final int ID_GAME_LEVEL = 9;
public static final int ID_GAME_SOUNDS = 10;
public static final int ID_GAME_VIBRA = 11;
public static final int ID_GAME_NAME = 12;
public static final int ID_GAME_LANGUAGE = 13;
// List of supported locales.
// The strings are Nokia-specific values
// of the "microedition.locale" system property.
public static final String[] supportedLocales ={"en", "fi-FI", "fr", "de"};
//NOTE: default language must be the first one
//for getString to work!
// Strings for each locale, indexed according to the
// contents of supportedLocales
private static final String[][] strings = {
{ "New game", "Settings", "High scores", "Instructions", "About", "Continue", "Back", "More", "Exit game","Level", "Sounds", "Shakes", "Game name", "Language"},
{ "Uusi peli", "Asetukset", "Huipputulokset", "Peliohjeet", "Tietoja", "Jatka", "Poistu", "Jatka", "Poistu", "Vaikeusaste", "Peli??net","V?rin?tehosteet", "Pelin nimi", "Language"},
{ "Nouveau jeu", "Paramètres", "Scores", "Instructions", "A propos", "Continuer","Retour", "Suite", "Sortir", "Niveau", "Sons", "Vibrations", "Jeu nom", "Language"},
{ "Neues Spiel", "Einstellungen","Rekord", "Anleitung", "über", "Weiter", "Zurück", "Weiter", "Beenden", "Ebene", "Ton", "Vibrationen", "Spiel name", "Language"}};
public static String getString(String lang,int key)
{
String locale = lang;
if (locale == null)
{
locale = new String(""); // use empty instead of null
}
// find the index of the locale id
int localeIndex = -1;
for (int i = 0; i < supportedLocales.length; i++)
{
if (locale.equals(supportedLocales[i]))
{
localeIndex = i;
break;
}
}
// not found
if (localeIndex == -1)
{
// defaults to first language, in this example English
return strings[0][key];
}
return strings[localeIndex][key];
}
public static String getString(int key)
{
String locale = System.getProperty("microedition.locale");
if (locale == null)
{
locale = new String(""); // use empty instead of null
}
// find the index of the locale id
int localeIndex = -1;
for (int i = 0; i < supportedLocales.length; i++)
{
if (locale.equals(supportedLocales[i]))
{
localeIndex = i;
break;
}
}
// not found
if (localeIndex == -1)
{
// defaults to first language, in this example English
return strings[0][key];
}
return strings[localeIndex][key];
}
}
Seconds.java
public class Seconds extends Thread
{
private int second=0;
private boolean running;
private AirFighterCanvas t;
public Seconds(AirFighterCanvas t)
{
this.t=t;
}
public void start()
{
running=true;
super.start();
}
public void halt()
{
running=false;
}
public void run()
{
while(running)
{
second++;
//t.repaint();
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
}
}
}
public int getSecond()
{
return second;
}
}
SplashCanvas.java
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;
public class SplashCanvas extends Canvas
{
private AirFighterMIDlet parent = null;
private MainMenu menu = null;
private Timer timer = null;
private Image img;
public SplashCanvas(AirFighterMIDlet parent)
{
this.parent = parent;
menu = new MainMenu(Resources.getString(Resources.ID_GAME_NAME),List.IMPLICIT, parent);
startTimer();
try
{
img=Image.createImage("/res/LogoImage.png");
}
catch(Exception e)
{
System.out.println("Splash Image create Error:");
System.out.println(e.toString());
}
}
protected void paint(Graphics g)
{//Do the splash screen here
//gi.setColor(0x1211FF);
//gi.fillRect(0,0 ,getWidth(),getHeight());
g.drawImage(img, (this.getWidth()-img.getWidth())/2,(this.getHeight()-img.getHeight())/2,16|4);//16TOP|4LEFT|1HCENTER
//g.setColor(0,0,0);
}
protected void keyPressed(int keyCode)
{
timer.cancel();
timer = null;
//All key events received set the main menu to the screen
parent.setDisplayable(menu);
}
//Timer for the splash screen. Main menu is set to the display
//after 5 seconds.
private void startTimer()
{
TimerTask task =new TimerTask()
{public void run()
{
parent.setDisplayable(menu);
}
};
timer = new Timer();
timer.schedule(task, 5000);
}
}
StarHScroller.java
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.util.*;
public class StarHScroller
{
public final int NUM_STARS = 30;
public final int WIDTH, HEIGHT;
public int []posX = new int[NUM_STARS];
public int []posY = new int[NUM_STARS];
public int []size = new int[NUM_STARS];
int[] raw;
Image image = null;
Graphics g;
Random r = new Random();
int bgColor = 0x00;
int fgColor = 0xFFFFFF;
public StarHScroller(int w, int h)
{
WIDTH = w;
HEIGHT = h;
try
{
image = Image.createImage(WIDTH, HEIGHT);
g = image.getGraphics();
}
catch(Exception e)
{
e.printStackTrace();
}
raw = new int[image.getWidth() * image.getHeight()];
for(int i=0; i<NUM_STARS; i++)
{
size[i] = r.nextInt(2)+1;
posX[i] = r.nextInt(WIDTH);
posY[i] = r.nextInt(HEIGHT) + 1;
}
}
private void initStar(int index)
{
size[index] = r.nextInt(2)+1;
posX[index] = -10 + r.nextInt(10);;
posY[index] = r.nextInt(HEIGHT) + 1;
}
public void draw()
{
g.setColor(fgColor);
for(int i=0; i<NUM_STARS; i++)
{
g.fillRect(posX[i], posY[i], size[i], size[i]);
switch(size[i])
{
case 1:
posX[i] +=1;
break;
case 2:
posX[i] +=2;
break;
}
if(posX[i] > WIDTH)
{
initStar(i);
}
}
}
public byte[] getByteArray(Image image)
{
int raw[] = new int[image.getWidth() * image.getHeight()];
image.getRGB(raw, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
byte rawByte[] = new byte[image.getWidth() * image.getHeight() * 4]; int n = 0;
for(int i = 0; i < raw.length; i++)
{
// break up into channels
int ARGB = raw[i];
int a = (ARGB & 0xff000000) >> 24; // alpha channel!
int r = (ARGB & 0xff0000) >> 16; // red channel!
int g = (ARGB & 0x0000ff00) >> 8; // green channel!
int b = ARGB & 0x000000ff; // blue channel !
rawByte[n] = (byte)b;
rawByte[n + 1] = (byte)g;
rawByte[n + 2] = (byte)r;
rawByte[n + 3] = (byte)a;
// you can see these codes
// from "http://forum.java.sun.com/thread.jspa?forumID=76&threadID=629677"
// put the color back together
//argb = ((a << 24) | (r << 16) | (g << 8) | b);
n += 4;
}
raw = null;
return rawByte;
}
public void updateImage()
{
g.setColor(bgColor);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.setColor(fgColor);
draw();
}
public Image getImage()
{
g.setColor(bgColor);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.setColor(fgColor);
draw();
return image;
}
}